Secure Your Spring Boot Backend and Angular Frontend with Okta


Securing a Spring Boot backend and Angular frontend with Okta involves integrating authentication and authorization into both the backend and frontend using Okta's Identity Management platform. Here's a step-by-step guide:


Backend (Spring Boot with Okta OAuth2 Integration)

1. Set Up Okta Developer Account

  1. Go to Okta Developer and create an account.
  2. Once logged in, create a new OAuth 2.0 Application in the Okta dashboard:
    • Choose Web as the platform.
    • Set up the Redirect URI to http://localhost:8080/login/oauth2/code/okta for local development.
    • Set Grant Type to Authorization Code.
  3. After creating the app, note the Client ID, Client Secret, and Issuer URL (e.g., https://dev-XXXX.okta.com/oauth2/default).

2. Add Dependencies to pom.xml

Add the required dependencies for Spring Security OAuth2 and Okta to your pom.xml:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-oauth2-jose</artifactId>
    </dependency>
</dependencies>

3. Configure application.yml

In src/main/resources/application.yml, configure your Okta OAuth2 settings:

spring:
  security:
    oauth2:
      client:
        registration:
          okta:
            client-id: YOUR_OKTA_CLIENT_ID
            client-secret: YOUR_OKTA_CLIENT_SECRET
            scope: openid, profile, email
            authorization-grant-type: authorization_code
            redirect-uri: "{baseUrl}/login/oauth2/code/okta"
            client-name: Okta
        provider:
          okta:
            issuer-uri: https://dev-XXXX.okta.com/oauth2/default

4. Configure Spring Security

Create a SecurityConfig class to secure your application routes:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/", "/login", "/error").permitAll()  // Public pages
                .anyRequest().authenticated()  // Secure pages
            .and()
            .oauth2Login()  // Enable OAuth2 login flow
                .loginPage("/login")
            .and()
            .logout()
                .logoutSuccessUrl("/")
                .permitAll();

        return http.build();
    }
}

In this configuration:

  • /, /login, and /error are publicly accessible.
  • All other routes require authentication via OAuth2 login.

5. Create a Controller

Create a simple controller to test the secured and public routes:

@RestController
public class HomeController {

    @GetMapping("/")
    public String home() {
        return "Welcome to the home page! Public access.";
    }

    @GetMapping("/user")
    public String user(Authentication authentication) {
        return "Hello, " + authentication.getName() + "! You are authenticated.";
    }
}

6. Run the Spring Boot Application

Start the Spring Boot application (mvn spring-boot:run).

  • When accessing a protected route (e.g., /user), the application will redirect to Okta for authentication.

Frontend (Angular with Okta Authentication)

1. Set Up Okta for Angular

  1. Go to Okta Developer and create a new Single Page Application (SPA).
  2. Note down the Client ID, Issuer URL, and Redirect URIs (e.g., http://localhost:4200/callback).

2. Install Okta SDK for Angular

Install the Okta Angular SDK:

npm install @okta/okta-angular @okta/okta-auth-js

3. Configure Okta in app.module.ts

In src/app/app.module.ts, configure Okta settings:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { OktaAuthModule, OktaConfig } from '@okta/okta-angular';

const oktaConfig: OktaConfig = {
  clientId: 'YOUR_OKTA_CLIENT_ID',
  issuer: 'https://dev-XXXX.okta.com/oauth2/default',
  redirectUri: window.location.origin + '/callback',
  scope: 'openid profile email'
};

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    OktaAuthModule.initAuth(oktaConfig),
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {}

4. Create an Auth Service

Create a service to manage login and logout:

import { Injectable } from '@angular/core';
import { OktaAuthService } from '@okta/okta-angular';
import { Router } from '@angular/router';

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  constructor(private oktaAuth: OktaAuthService, private router: Router) {}

  login() {
    this.oktaAuth.signInWithRedirect();
  }

  logout() {
    this.oktaAuth.signOut();
  }

  isAuthenticated(): Promise<boolean> {
    return this.oktaAuth.isAuthenticated();
  }
}

5. Set Up the Callback Component

Create a callback.component.ts to handle the OAuth2 callback and token storage:

import { Component, OnInit } from '@angular/core';
import { OktaAuthService } from '@okta/okta-angular';
import { Router } from '@angular/router';

@Component({
  selector: 'app-callback',
  template: `<h2>Loading...</h2>`
})
export class CallbackComponent implements OnInit {
  constructor(private oktaAuth: OktaAuthService, private router: Router) {}

  ngOnInit() {
    this.oktaAuth.handleAuthentication().then(() => {
      this.router.navigate(['/']);
    });
  }
}

6. Add Protected Routes

Set up routes in app-routing.module.ts and protect them with OktaAuthGuard:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { CallbackComponent } from './callback/callback.component';
import { OktaAuthGuard } from '@okta/okta-angular';

const routes: Routes = [
  { path: '', component: AppComponent },
  { path: 'callback', component: CallbackComponent },
  { path: 'profile', component: ProfileComponent, canActivate: [OktaAuthGuard] }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule {}

7. Update HTML for Login and Logout

In app.component.html, create UI elements for login/logout:

<button *ngIf="!(isAuthenticated | async)" (click)="login()">Login</button>
<button *ngIf="isAuthenticated | async" (click)="logout()">Logout</button>

8. Run the Angular App

Ensure your Angular app is running (ng serve).

  • The redirect URI should be set correctly (e.g., http://localhost:4200/callback).
  • After login, Okta will handle the OAuth2 flow, and the user will be authenticated in the backend (Spring Boot).

Final Steps:

  • Test the flow: Start both your Spring Boot application and Angular frontend.
    • Visit the Angular app (http://localhost:4200).
    • Click Login and Okta will authenticate the user.
    • Upon success, you'll be redirected to the protected routes (e.g., /profile).
    • Spring Boot will authorize the user based on the OAuth2 token provided by Okta.

Popular posts from this blog

Learn Java 8 streams with an example - print odd/even numbers from Array and List

Java Stream API - How to convert List of objects to another List of objects using Java streams?

Registration and Login with Spring Boot + Spring Security + Thymeleaf

Java, Spring Boot Mini Project - Library Management System - Download

ReactJS, Spring Boot JWT Authentication Example

Top 5 Java ORM tools - 2024

Java - Blowfish Encryption and decryption Example

Spring boot video streaming example-HTML5

Google Cloud Storage + Spring Boot - File Upload, Download, and Delete