Usando JWT com Spring Security OAuth
1. Visão geral
Neste tutorial, discutiremos como obter nossa implementação Spring Security OAuth2 para usar Tokens da Web JSON.
Também estamos continuando a construir sobrethe previous article nesta série OAuth.
Leitura adicional:
Logout em um aplicativo protegido OAuth
Um aprofundamento prático sobre como implementar logout em um aplicativo Spring Security OAuth2 com JWT.
OAuth2 Lembre-se de mim com o token de atualização
Aprenda a implementar a funcionalidade de lembrança de mim com um front end Angular, para um aplicativo protegido com Spring Security e OAuth2.
OAuth2 para uma API REST do Spring - manipule o token de atualização no AngularJS
Aprendemos como armazenar o token de atualização em um aplicativo cliente AngularJS, como atualizar um token de acesso expirado e como aproveitar o proxy Zuul.
Antes de começarmos - uma observação importante. Lembre-se de quethe Spring Security core team is in the process of implementing a new OAuth2 stack - com alguns aspectos já destacados e outros ainda em andamento.
Aqui está um vídeo rápido que lhe dará algum contexto sobre esse esforço:
Tudo bem, vamos começar.
2. Configuração do Maven
Primeiro, precisamos adicionar a dependênciaspring-security-jwt ao nossopom.xml:
org.springframework.security
spring-security-jwt
Observe que precisamos adicionar a dependênciaspring-security-jwt para o Authorization Server e o Resource Server.
3. Servidor de Autorização
A seguir, configuraremos nosso servidor de autorização para usarJwtTokenStore - da seguinte maneira:
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.tokenStore(tokenStore())
.accessTokenConverter(accessTokenConverter())
.authenticationManager(authenticationManager);
}
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("123");
return converter;
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
}
}
Observe que usamossymmetric key em nossoJwtAccessTokenConverter para assinar nossos tokens - o que significa que precisaremos usar a mesma chave exata para o Servidor de Recursos também.
4. Servidor de Recursos
Agora, vamos dar uma olhada em nossa configuração do servidor de recursos - que é muito semelhante à configuração do servidor de autorização:
@Configuration
@EnableResourceServer
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(ResourceServerSecurityConfigurer config) {
config.tokenServices(tokenServices());
}
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("123");
return converter;
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
return defaultTokenServices;
}
}
Lembre-se de que estamos definindo esses dois servidores como totalmente separados e implantáveis de forma independente. Essa é a razão pela qual precisamos declarar alguns dos mesmos beans novamente aqui, na nova configuração.
5. Reivindicações personalizadas no token
Vamos agora configurar alguma infraestrutura para poder adicionar algunscustom claims in the Access Token. As declarações padrão fornecidas pela estrutura são muito boas, mas na maioria das vezes precisaremos de algumas informações extras no token para utilizar no lado do cliente.
Definiremos umTokenEnhancer para personalizar nosso token de acesso com essas declarações adicionais.
No exemplo a seguir, adicionaremos um campo extra “organization” ao nosso token de acesso - com esteCustomTokenEnhancer:
public class CustomTokenEnhancer implements TokenEnhancer {
@Override
public OAuth2AccessToken enhance(
OAuth2AccessToken accessToken,
OAuth2Authentication authentication) {
Map additionalInfo = new HashMap<>();
additionalInfo.put(
"organization", authentication.getName() + randomAlphabetic(4));
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(
additionalInfo);
return accessToken;
}
}
Em seguida, conectaremos isso em nossa configuraçãoAuthorization Server - da seguinte maneira:
@Override
public void configure(
AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
tokenEnhancerChain.setTokenEnhancers(
Arrays.asList(tokenEnhancer(), accessTokenConverter()));
endpoints.tokenStore(tokenStore())
.tokenEnhancer(tokenEnhancerChain)
.authenticationManager(authenticationManager);
}
@Bean
public TokenEnhancer tokenEnhancer() {
return new CustomTokenEnhancer();
}
Com essa nova configuração instalada e em execução, veja como seria uma carga útil de token:
{
"user_name": "john",
"scope": [
"foo",
"read",
"write"
],
"organization": "johnIiCh",
"exp": 1458126622,
"authorities": [
"ROLE_USER"
],
"jti": "e0ad1ef3-a8a5-4eef-998d-00b26bc2c53f",
"client_id": "fooClientIdPassword"
}
5.1. Use o token de acesso no cliente JS
Por fim, queremos usar as informações do token em nosso aplicativo cliente AngualrJS. Usaremos a bibliotecaangular-jwt para isso.
Então, o que vamos fazer é usar a declaração “organization” em nossoindex.html:
Related
- Um guia rápido para usar o Cloud Foundry UAA
- Autenticando com Reddit OAuth2 e Spring Security
- Suporte para Spring WebClient e OAuth2
- Logout em um aplicativo protegido OAuth
- Login OAuth do Spring Security com WebFlux
- Spring Security 5 - Login do OAuth2
- OAuth2 Lembre-se de mim com o token de atualização
- Implementando a estrutura de autorização do OAuth 2.0 usando Java EE
- OAuth2 para uma API REST do Spring - manipule o token de atualização no AngularJS
- OAuth2.0 e registro de cliente dinâmico