Okta: secure access to Angular + Spring Boot applications

« Spring Framework».



- « Spring-». , Spring Boot :

- properties vs. YAML

- @Value + SpEL

- @ConfigurationProperties

- Externalized .

!






-, . , .





Okta — , . Okta, , , . - . , , . , Okta , .





Okta OAuth2. OAuth2 Open ID Connect (OIDC) Okta.





«» , , . «», Okta. : « - Spring Boot + Angular».





, , GitHub.





:





Component architecture of the Contacts application using the OAuth protocol
«», OAuth

, Kubernetes, :





Kubernetes: Angular + Java / Spring Boot Google Kubernetes Engine (GKE)





Kubernetes: Angular + Spring Boot Microsoft Azure





Okta

Okta Okta. .





Okta. Applications () Add Application ( ).





Single Page App ( ) , . Authorization code ( ), , URL- ( Okta).





: -, , Okta , - — API . PKCE.





OAuth « » (authorization code flows) — . , OAuth , Medium Okta. Angular, (implicit flow) (Proof Key Code Exchange, PKCE).









. , Okta . , ; Okta .





Okta, , .





(groups claims) «»

Admin. //.





, , Okta. Okta Spring Boot - Okta. . , .





, , .





Group management

 





Assigning groups / users for the application
/
Adding a Group Statement to the Access Token Issued by the Authorization Server
,

Okta , «» .





Okta

«» SDK- Okta Angular. , , Okta. npm



:





npm install @okta/okta-angular --save
      
      



, OIDC, . URL- Okta — Okta.





app.module.ts true PKCE.





const oktaConfig = {
issuer: 'https://{yourOktaDomain}/oauth2/default',
redirectUri: window.location.origin + '/implicit/callback',
clientId: 'your clientId',
pkce: true
};
      
      



providers. OktaAuthModule



:





import { OktaAuthModule, OktaCallbackComponent } from '@okta/okta-angular';
import {OKTA_CONFIG} from '@okta/okta-angular';
....
imports:[
...
OktaAuthModule
...
]
providers: [
...
{ provide: OKTA_CONFIG, useValue: oktaConfig }
...
]
      
      



, Route Guard Angular. app-routing-module.ts:





import { OktaCallbackComponent } from '@okta/okta-angular';
...
const routes: Routes = [
{ path: 'contact-list',
canActivate: [ OktaAuthGuard ],
component: ContactListComponent },
{ path: 'contact',
canActivate: [ OktaAuthGuard, AdminGuard ],
component: EditContactComponent },
{
path: 'implicit/callback',
component: OktaCallbackComponent
},
{ path: '',
redirectTo: 'contact-list',
pathMatch: 'full'
},
];
      
      



AuthGuard



, , ,  — AdminGuard



OktaAuthGuard



.





canActivate



OktaAuthGuard



, . , Okta; , , .





async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
this.authenticated = await this.okta.isAuthenticated();
if (this.authenticated) { return true; }
// Redirect to login flow.
this.oktaAuth.loginRedirect();
return false;
}
      
      



canActivate



AdminGuard



, Admin



; , .





async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
this.user = await this.okta.getUser();
const result = this.user.groups.find((group) => group === 'Admin');
if (result) {
return true;
} else {
alert('User is not authorized to perform this operation');
return false; }
}
      
      



, , /contact-list .





Sequence of operations for displaying contacts on the screen

, PKCE. , URL- , , . . PKCE SHA256 (code verifier), (code challenge). , SHA256 .





Angular : SHA256 , .





Implicit grant using PKCE in Contacts app
(implicit grant) PKCE «»

Okta

Spring Boot Okta, :





<dependency>
<groupId>com.okta.spring</groupId>
<artifactId>okta-spring-boot-starter</artifactId>
<version>1.2.1</version>
<exclusions>
<exclusion>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.4.0.RELEASE</version>
</dependency>
      
      



Spring Security OAuth2 Okta Spring Boot Starter classpath, Spring Okta .





Spring Okta:





okta.oauth2.client-id=<clientId>
okta.oauth2.issuer=https://{yourOktaDomain}/oauth2/default
okta.oauth2.groups-claim=groups
      
      



SpringSecurity



, Spring Boot :





@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Profile("dev")
@Slf4j
public class SecurityDevConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception{
http.cors().and().csrf().disable();
http.cors().configurationSource(request -> new CorsConfiguration(corsConfiguratione()));
// http.authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
// .and().
http.antMatcher("/**")
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.antMatchers("/").permitAll()
.anyRequest().authenticated();
http.oauth2ResourceServer();
}
      
      



. /contacts http://localhost:8080/api/contacts, 401, .





, , SpringSecurityConfig



:





@EnableGlobalMethodSecurity(prePostEnabled = true)
      
      



, , PreAuthorize



:





@PreAuthorize("hasAuthority('Admin')")
public Contact saveContact(@RequestBody Contact contact,@AuthenticationPrincipal Principal userInfo) {
      
      



Principal



(@AuthenticationPrincipal



).





API

Okta , . API, . Angular HttpInterceptor



. HTTP- :





private async handleAccess(request: HttpRequest<any>, next: HttpHandler): Promise<HttpEvent<any>> {
const accessToken = await this.oktaAuth.getAccessToken();
if ( accessToken) {
request = request.clone({
setHeaders: {
Authorization: 'Bearer ' + accessToken
}
});
}
return next.handle(request).toPromise();
}
}
      
      



API API





, API . , , , . , JavaScript-. API API, Okta «-», ( Okta).





, . - PKCE, ( API Okta , API). .





 





Sequence of operations for direct access to the server API
API

API,   -, API, API.





, API, .





- API . Spring Cloud OpenFeign, REST-. -. - REST, , , API. . Feign .





, . . , Kubernetes, :





Kubernetes: Angular + Java / Spring Boot Google Kubernetes Engine (GKE)





Kubernetes: Angular + Spring Boot Microsoft Azure






« Spring Framework»





« Spring-»








All Articles