【问题标题】:Spring Security bcrypt doesn't matchSpring Security bcrypt 不匹配
【发布时间】:2019-03-25 10:09:40
【问题描述】:

我使用BCryptPasswordEncoder

我的密码经过哈希处理后是这样的:

$2a$04$oPljpAgVziMVABHS.z.znOhhu7oi8N5pxt0MS6IbOTWn.onfulrZe。

当我测试时,它会在控制台上写下密码看起来不像 BCrypt。

我使用BCryptPasswordEncoder 类 (\A\$2a?\$\d\d\$[./0-9A-Za-z]{53}) 中的正则表达式使用 http://regexr.com 对其进行了测试,但它不匹配。

我尝试在开头使用 A 并且它匹配。
我已经重试了我的应用程序,但我遇到了同样的错误。
你知道追加什么吗?

编辑

Encoders.java

public class Encoders {

    @Bean
    public PasswordEncoder oauthClientPasswordEncoder() {
        return new BCryptPasswordEncoder(4);
    }
    @Bean
    public PasswordEncoder userPasswordEncoder() {
        return new BCryptPasswordEncoder(8);
    }
}

SecurityConfig.java

@Configuration
@EnableWebSecurity
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
@Import(Encoders.class)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private PasswordEncoder userPasswordEncoder;

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(userPasswordEncoder);
    }
}

ResourceServerConfig.java

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    private static final String RESOURCE_ID = "resource-server-rest-api";
    private static final String SECURED_READ_SCOPE = "#oauth2.hasScope('read')";
    private static final String SECURED_WRITE_SCOPE = "#oauth2.hasScope('write')";
    private static final String SECURED_PATTERN = "/api/**";

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.resourceId(RESOURCE_ID);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.requestMatchers()
                .antMatchers(SECURED_PATTERN).and().authorizeRequests()
                .antMatchers(HttpMethod.POST, SECURED_PATTERN).access(SECURED_WRITE_SCOPE)
                .anyRequest().access(SECURED_READ_SCOPE);
    }
}

AuthorizationServerConfig.java

@Configuration
@EnableAuthorizationServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Import(SecurityConfig.class)
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    @Qualifier("dataSource")
    private DataSource dataSource;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private PasswordEncoder oauthClientPasswordEncoder;

    @Bean
    public TokenStore tokenStore() {
        return new JdbcTokenStore(dataSource);
    }

    @Bean
    public OAuth2AccessDeniedHandler oauthAccessDeniedHandler() {
        return new OAuth2AccessDeniedHandler();
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
        oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()").passwordEncoder(oauthClientPasswordEncoder);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.jdbc(dataSource);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints.tokenStore(tokenStore()).authenticationManager(authenticationManager).userDetailsService(userDetailsService);
    }
}

数据.sql

INSERT INTO OAUTH_CLIENT_DETAILS(CLIENT_ID, RESOURCE_IDS, CLIENT_SECRET, SCOPE, AUTHORIZED_GRANT_TYPES, AUTHORITIES, ACCESS_TOKEN_VALIDITY, REFRESH_TOKEN_VALIDITY)
 VALUES ('moha_security', 'resource-server-rest-api', 'A$2a$04$oPljpAgVziMVABHS.z.znOhhu7oi8N5pxt0MS6IbOTWn.onfulrZe',
 'read', 'password,authorization_code,refresh_token,implicit', 'USER', 10800, 2592000);

我对邮递员的要求

curl -X POST \
  http://localhost:8080/oauth/token \
  -H 'Postman-Token: 75a237ed-2e27-4af6-bca5-de558627f460' \
  -H 'cache-control: no-cache' \
  -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \
  -F grant_type=password \
  -F username=201806ALE199501 \
  -F 'password=$2a$08$c.LqCdhrpAiF2Qn7yPGEw.6uL/phlSDW.QNXfMMWtnzSVX/paf2nK' \
  -F client_id=moha_security

我在 IntelliJ 控制台中的结果

2018-10-22 14:48:05.180  WARN 3483 --- [nio-8080-exec-5] o.s.s.c.bcrypt.BCryptPasswordEncoder     : Encoded password does not look like BCrypt

【问题讨论】:

  • 您的 SQL 脚本错误,请从 A$2a$04$oPljpAgVziMVABHS.z.znOhhu7oi8N5pxt0MS6IbOTWn.onfulrZe 中删除 A。另外您的 cURL 命令有误,请将$2a$08$c.LqCdhrpAiF2Qn7yPGEw.6uL/phlSDW.QNXfMMWtnzSVX/paf2nK 替换为纯文本密码。

标签: java spring-security bcrypt


【解决方案1】:

你的代码完全没问题。

来自维基百科: 影子密码文件中哈希字符串中的前缀“$2a$”或“$2b$”(或“$2y$”)表示哈希字符串是模块化密码格式的 bcrypt 哈希。哈希字符串的其余部分包括成本参数、128 位盐(Radix-64 编码为 22 个字符)和 184 位生成的哈希值。

关于 A,这只是令人困惑, 这是一个小解释: When should I use \A in a regex?

【讨论】:

  • 感谢您的精确。你知道为什么 BCryptPasswordEncoder 不匹配我的密码吗?
【解决方案2】:

我相信您缺少用户角色定义。首先在数据库中填充您的角色。

【讨论】:

    猜你喜欢
    • 2015-12-31
    • 2019-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-09
    • 1970-01-01
    • 2012-05-01
    • 2012-10-01
    相关资源
    最近更新 更多