Application Web
Pour une application à l’ancienne, on utilise le flux Authorization Code Grant, qui implique un User Agent, un Client et l'Authorization Server.
Dépendances
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
WebSecurityConfigurerAdapter
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/echo/**").authenticated()
.antMatchers("/").permitAll()
.and()
.oauth2Login();
}
}
Configuration YAML
4 providers prédéfinis
-
Google
-
Github
-
Facebook
-
Okta
Provider maison (exemple avec Keycloak)
spring:
security:
oauth2:
client:
registration:
keycloak:
client-id: example-client
client-secret: example-secret
authorization-grant-type: authorization_code
redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
client-authentication-method: basic
client-name: Keycloak
scope:
- openid
- profile
- email
- address
- phone
provider:
keycloak:
authorization-uri: http://localhost:8888/auth/realms/example-realm/protocol/openid-connect/auth
token-uri: http://localhost:8888/auth/realms/example-realm/protocol/openid-connect/token
jwk-set-uri: http://localhost:8888/auth/realms/example-realm/protocol/openid-connect/certs
Configuration par code
Un peu plus de code, et un peu moins de YAML, en remplacement de gros application.yml précédent.
example:
keycloak:
client-id: example-client
client-secret: example-secret
base-url: http://localhost:8888
realm: example-realm
@Configuration
public class KeycloakConfig {
@Value("${example.keycloak.client-id}")
private String clientId;
@Value("${example.keycloak.client-secret}")
private String clientSecret;
@Value("${example.keycloak.base-url}")
private String baseUrl;
@Value("${example.keycloak.realm}")
private String realm;
@Bean
public ClientRegistrationRepository clientRegistrationRepository() {
return new InMemoryClientRegistrationRepository(this.keycloakClientRegistration());
}
private ClientRegistration keycloakClientRegistration() {
return ClientRegistration.withRegistrationId("keycloak")
.clientId(clientId)
.clientSecret(clientSecret)
.clientAuthenticationMethod(ClientAuthenticationMethod.BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
.scope("openid", "profile", "email", "address", "phone")
.clientName("Keycloak")
.authorizationUri(baseUrl + "/auth/realms/" + realm + "/protocol/openid-connect/auth")
.tokenUri(baseUrl + "/auth/realms/" + realm + "/protocol/openid-connect/token")
.jwkSetUri(baseUrl + "/auth/realms/" + realm + "/protocol/openid-connect/certs")
.build();
}
}
Username
private String getUsername() {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
return ((DefaultOidcUser)principal).getPreferredUsername();
}
Application SPA
Pour une application plus moderne en Single Page Application, le serveur Spring joue le rôle de Resource Server.
Dépendances
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
WebSecurityConfigurerAdapter
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/echo/**").authenticated()
.antMatchers("/").permitAll()
.and()
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
}
}
Configuration YAML
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: http://localhost:8888/auth/realms/example-realm
Username
private String getUsername() {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
return ((Jwt)principal).getClaimAsString("preferred_username");
}