将JWT与Spring Security OAuth结合使用

1.概述

在本教程中,我们将讨论如何使用Spring Security OAuth2实现来使用JSON Web令牌

我们还将继续构建此OAuth系列的上一篇文章

2. Maven配置

首先,我们需要在我们的pom.xml中添加spring-security-jwt依赖项:


    org.springframework.security
    spring-security-jwt

请注意,我们需要将spring-security-jwt依赖项添加到Authorization Server和Resource Server

3.授权服务器

接下来,我们将配置我们的授权服务器以使用JwtTokenStore - 如下所示:

@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;
    }
}

请注意,我们在JwtAccessTokenConverter中使用对称密钥来签署我们的令牌 - 这意味着我们还需要为Resources Server使用相同的密钥

4.资源服务器

现在,让我们看看我们的资源服务器配置 - 这与授权服务器的配置非常相似:

@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;
    }
}

请记住,我们将这两个服务器定义为完全独立且可独立部署。这就是我们需要在新配置中再次声明一些相同bean的原因。

5.令牌中的自定义Claims

现在让我们设置一些基础设施,以便能够在Access Token中添加一些自定义声明

框架提供的标准声明都很好,但大多数时候我们需要在令牌中使用一些额外的信息才能在客户端使用。框架提供的标准声明都很好,但大多数时候我们需要在令牌中使用一些额外的信息才能在客户端使用

我们将定义TokenEnhancer以使用这些附加声明来自定义我们的访问令牌

在下面的示例中,我们将使用此CustomTokenEnhancer向我们的访问令牌添加一个额外的字段“组织”

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;
    }
}

然后,我们将它连接到我们的授权服务器配置 - 如下所示:

@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();
}

启动并运行此新配置 :

{
    "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。使用JS Client中的Access Token

最后,我们希望在AngualrJS客户端应用程序中使用令牌信息。我们将使用angular-jwt库。

那么我们要做的就是在index.html中使用“组织”声明:


 

 

                    
                    

你可能感兴趣的:(将JWT与Spring Security OAuth结合使用)