Spring Security OAuth2 - JWT与客户端和用户的数据库

时间:2018-01-08 20:55:27

标签: java spring spring-security spring-security-oauth2

根据我对Spring OAuth2实现的理解,ClientDetailsConfiguration和TokenStore不一定是依赖的。从本质上讲,我认为应该能够使用JWTokenStore(其中令牌本身不存储在数据库中)与数据库来容纳客户端凭据。然而,虽然我已经引用了关于该主题的多篇文章,但大多数(为了说明/简单),只需硬编码客户端凭证或将它们放在属性文件中。

例如(source):

      @Override
   public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
      configurer
              .inMemory()
              .withClient(clientId)
              .secret(clientSecret)
              .authorizedGrantTypes(grantType)
              .scopes(scopeRead, scopeWrite)
              .resourceIds(resourceIds);
   }

但是,我需要将客户端详细信息存储在数据库中。我觉得它很直接;也就是说,我认为我可以通过设置JWTokenStore和JDBC客户端后端来实现所需的结果。

的AppConfig

@Configuration
public class AppConfig {


    @Value("${spring.datasource.url}")
    private String datasourceUrl;

    @Value("${spring.datasource.driverClassName}")
    private String dbDriverClassName;

    @Value("${spring.datasource.username}")
    private String dbUsername;

    @Value("${spring.datasource.password}")
    private String dbPassword;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public DataSource dataSource() {
        final DriverManagerDataSource dataSource = new DriverManagerDataSource();

        dataSource.setDriverClassName(dbDriverClassName);
        dataSource.setUrl(datasourceUrl);
        dataSource.setUsername(dbUsername);
        dataSource.setPassword(dbPassword);

        return dataSource;
    }    

       @Bean
       public JwtAccessTokenConverter accessTokenConverter() {
          JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
          converter.setSigningKey("123");
          return converter;
       }


       @Bean
       public TokenStore tokenStore() {
          return new JwtTokenStore(accessTokenConverter());
       }

AuthServerConfig

 @EnableAuthorizationServer
@Configuration
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter{
    @Autowired
private TokenStore tokenStore;

 private final AppConfig appConfig; 

private AuthenticationManager authenticationManager;

@Autowired
public AuthServerConfig(AuthenticationManager authenticationManager, AppConfig appConfig) {
    this.authenticationManager = authenticationManager;
    this.appConfig = appConfig;
}

@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
    security.checkTokenAccess("permitAll()");
}

@Override
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {


    configurer.jdbc(appConfig.dataSource());
}

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
    endpoints.tokenStore(tokenStore)
            .tokenEnhancer(enhancerChain)
        .authenticationManager(authenticationManager);
}



   @Bean
   @Primary //Making this primary to avoid any accidental duplication with another token service instance of the same name
   public DefaultTokenServices tokenServices() {
      DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
      defaultTokenServices.setTokenStore(tokenStore);
      defaultTokenServices.setSupportRefreshToken(true);
      return defaultTokenServices;
   }

不是返回JWT,而是返回“正常”(缺少更好的术语)访问令牌:

    {
    "access_token": "11129068-ad5f-4440-a4d1-6501f01e100b",
    "token_type": "bearer",
    "expires_in": 899,
    "scope": "read"
}

如何将JWT与存储在数据库中的客户端凭证一起使用?

感谢。

1 个答案:

答案 0 :(得分:0)

您还应该将accessTokenConverter设置为端点,如下所示。

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
    endpoints.tokenStore(tokenStore)
             .accessTokenConverter(accessTokenConverter())
             .tokenEnhancer(enhancerChain)
             .authenticationManager(authenticationManager);
}