【问题标题】:Spring Security OAuth2 - JWT's with Database for Clients and UsersSpring Security OAuth2 - 用于客户端和用户的带有数据库的 JWT
【发布时间】:2019-04-05 17:47:55
【问题描述】:

根据我对 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 客户端后端来达到预期的效果。

应用配置

@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 与存储在数据库中的客户端凭据一起使用?

谢谢。

【问题讨论】:

  • 您是在尝试生成 JWT 令牌还是使用并验证它?
  • 最终目标是两者兼得。但是,上面的代码是针对生成块的;我正在尝试分离授权和资源服务器。谢谢。
  • JwtTokenStore 用于验证和解析 JWT 令牌。为了从数据库创建 JWT 令牌,您需要从数据库中读取信息并使用 jsonwebtoken 或 nimbusds 等库手动创建 JWT 令牌。
  • 这确实令人困惑,我仍然认为他们没有使用JwtTokenStore 来生成 JWT 令牌。因为如果您查看他们的完整 git 项目,他们正在使用 findTokensByClientId 获取新令牌,但该方法对 JwtTokenStore 的实现为空。
  • @Kelly,如果您记得解决方案,请随时为您自己的问题提供答案。我个人没有遇到你的具体问题。我主要想询问您有关在数据库中存储客户端凭据的用例。我决定反对它,因为我的 rest API 有两个客户端,它们都是内部的(网络和桌面)。您需要在数据库中存储客户端凭据的用例是什么?

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


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2012-10-22
    • 2020-04-06
    • 1970-01-01
    • 2023-04-06
    • 2013-06-20
    • 1970-01-01
    • 2015-11-05
    • 2019-10-02
    • 1970-01-01
    相关资源
    最近更新 更多