有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

使用OAuth2和JWT:Encoded密码的JavaSpring安全性看起来不像BCrypt

我正在尝试用JWT实现spring授权服务器。我能够生成JWT令牌并登录,直到我将BCrypt添加到混合中。现在,当我试图登录时,我从API中得到了“坏凭据”

OAuth2配置。爪哇

@Configuration
@EnableAuthorizationServer
public class OAuth2Configuration extends AuthorizationServerConfigurerAdapter {

    private DataSource dataSource;
    private AuthenticationManager authenticationManager;
    private BCryptPasswordEncoder passwordEncoder;

    public OAuth2Configuration(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
        this.dataSource = new Jdbc3PoolingDataSource();
        this.passwordEncoder = new BCryptPasswordEncoder();
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.passwordEncoder(passwordEncoder);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("api-client")
                .secret("verysecretivesecret")
                .scopes("READ", "WRITE", "DELETE")
                .authorizedGrantTypes("implicit", "refresh_tokens", "password", "authorization_code");
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authorizationCodeServices(authorizationCodeServices())
                .tokenStore(tokenStore())
                .tokenEnhancer(jwtTokenEnhancer())
                .authenticationManager(authenticationManager);
    }

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

    @Bean
    protected JwtAccessTokenConverter jwtTokenEnhancer() {
        return new JwtAccessTokenConverter();
    }

    @Bean
    protected AuthorizationCodeServices authorizationCodeServices() {
        return new JdbcAuthorizationCodeServices(dataSource);
    }

}

网络安全配置。爪哇

@Configuration
class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private AccountDetailsService accountDetailsService;
    private BCryptPasswordEncoder passwordEncoder;
    private DataSource dataSource;

    WebSecurityConfig(AccountDetailsService accountDetailsService) {
        this.accountDetailsService = accountDetailsService;
        this.dataSource = new Jdbc3PoolingDataSource();
        this.passwordEncoder = new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(accountDetailsService).passwordEncoder(passwordEncoder).and().jdbcAuthentication().dataSource(dataSource);
    }
}

种子数据。爪哇

@Override
public void run(String... args) throws Exception {      

    Stream.of("alan,test").map(x -> x.split(","))
            .forEach(tuple -> {
                Account user = new Account();
                user.setUsername(tuple[0]);
                user.setPassword(new BCryptPasswordEncoder().encode(tuple[1]));
                user.setEmail(tuple[0]);
                user.setRoles(Collections.singletonList(role));
                user.setActive(true);
                this.accountRepository.save(user);
            });
}

谢谢你的帮助


共 (2) 个答案

  1. # 1 楼答案

    我需要做以下改变才能让它工作。如果有人需要的话

    @Override
            protected void configure(AuthenticationManagerBuilder auth) throws Exception {
                auth.userDetailsService(accountDetailsService)
                        .passwordEncoder(passwordEncoder)
                        .and()
                        .authenticationProvider(authenticationProvider())
                        .jdbcAuthentication()
                        .dataSource(dataSource);
            }
    
        @Bean
        public DaoAuthenticationProvider authenticationProvider() {
            DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
            authenticationProvider.setUserDetailsService(accountDetailsService);
            authenticationProvider.setPasswordEncoder(passwordEncoder);
            return authenticationProvider;
        }
    
  2. # 2 楼答案

    这是因为您对WebSecurity和AuthorizationServer都应用了BCrypt。因此,您不仅需要在存储中保留BCrypt加密的用户密码,还需要为OAuth2保留BCrypt加密的客户端机密。我猜这不是你想接近的

    为了使代码正常工作,请删除

       @Override
        public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
            security.passwordEncoder(passwordEncoder);
        }
    

    或者手动加密你的“verysecretivisecret”