Java BCrypt:使用Spring Security的空编码密码

Java BCrypt:使用Spring Security的空编码密码,java,spring,spring-security,spring-data-jpa,bcrypt,Java,Spring,Spring Security,Spring Data Jpa,Bcrypt,帮助解决问题的代码示例: 问题 在尝试在Spring引导应用程序中实现jwt安全性时,我遇到了以下问题: 当我尝试通过邮递员使用x-www-form-urlencoded登录时,我收到一个错误“坏客户端凭据”,同时我知道凭据是正确的 当我查看日志时,我看到BCrypt发出了一个“空编码密码”警告。这很奇怪,因为当我通过MySQL解释器查看数据库时,我在数据库中看到了正确加密的密码 信息 我正在使用Hibernate构建一个MySQL数据库 编译“org.springframework.secur

帮助解决问题的代码示例

问题

在尝试在Spring引导应用程序中实现jwt安全性时,我遇到了以下问题:

当我尝试通过邮递员使用x-www-form-urlencoded登录时,我收到一个错误“坏客户端凭据”,同时我知道凭据是正确的

当我查看日志时,我看到BCrypt发出了一个“空编码密码”警告。这很奇怪,因为当我通过MySQL解释器查看数据库时,我在数据库中看到了正确加密的密码

信息

我正在使用Hibernate构建一个MySQL数据库

编译“org.springframework.security.oauth:spring-security-oauth2:2.3.6.RELEASE”

编译“org.springframework.security:springsecurity jwt:1.0.10.RELEASE”

编译“org.springframework.boot:springbootstarterdatajpa”

Java 1.8.0_212

我尝试的

在开始实施安全性之前,控制器、存储库和MySQL数据库都正常工作

当我在网上搜索这个问题时,有些人建议它与“loadUserByUsername”函数有关。但是当我调试该函数时,我注意到它根本没有被调用

我还尝试了允许程序中的每一条路径并禁用crsf 以防它与访问权有关,但两者都没有改变任何东西<代码>(http.requestMatchers.andMatcher(“/**”).permitAll()和().csrf().disable();)

更新:在数据库中放入无用户时,我仍然会收到相同的错误

一些代码:

loadUserByUsername方法:

@Override
public UserDetails loadUserByUsername(String userName) {
    return userRepository.findByUsername(userName)
            .map(user -> new User(
                        user.getUsername(),
                        user.getPassword(),
                        UserRoleAuthority.getAuthorities(user.getRoles())
                ))
            .orElseThrow(() -> new UsernameNotFoundException("Unknown user: " + userName));

}
authenticationprovider和passwordencoder:

@Bean
public DaoAuthenticationProvider getAuthenticationProvider() {
    DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
    authenticationProvider.setUserDetailsService(userDetailsService);
    authenticationProvider.setPasswordEncoder(passwordEncoder());
    return authenticationProvider;
}

@Bean
PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}
签名密钥:

@Bean
public JwtAccessTokenConverter jwtTokenEnhancer() {
    JwtAccessTokenConverter result = new JwtAccessTokenConverter();
    result.setSigningKey(signingKey);
    return result;
}
添加新用户:

            userRepository.save(new User()
                            .withUsername("test")
                            .withPassword(passwordEncoder.encode("password"))
                            .withFirst("Admin")
                            .withLast("Nator")
                            .withEmail("test@notadmin.com")
                            .withRole(new HashSet<>(Arrays.asList(Role.Admin, Role.NotAdmin)))
            );
最后,我的控制台

2019-06-12 10:29:58.460  INFO 25207 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate Core {5.3.9.Final}
2019-06-12 10:29:58.461  INFO 25207 --- [           main] org.hibernate.cfg.Environment            : HHH000206: hibernate.properties not found
2019-06-12 10:29:58.532  INFO 25207 --- [           main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.0.4.Final}
2019-06-12 10:29:58.599  INFO 25207 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
2019-06-12 10:29:59.092  INFO 25207 --- [           main] o.h.t.schema.internal.SchemaCreatorImpl  : HHH000476: Executing import script 'org.hibernate.tool.schema.internal.exec.ScriptSourceInputNonExistentImpl@c30f26d'
2019-06-12 10:29:59.098  INFO 25207 --- [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2019-06-12 10:29:59.382  WARN 25207 --- [           main] o.s.s.o.p.t.s.JwtAccessTokenConverter    : Unable to create an RSA verifier from verifierKey (ignoreable if using MAC)
2019-06-12 10:29:59.595  INFO 25207 --- [           main] o.s.s.web.DefaultSecurityFilterChain     : Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/oauth/token'], Ant [pattern='/oauth/token_key'], Ant [pattern='/oauth/check_token']]], [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@56a72887, org.springframework.security.web.context.SecurityContextPersistenceFilter@1ddba7a0, org.springframework.security.web.header.HeaderWriterFilter@7adbec34, org.springframework.security.web.authentication.logout.LogoutFilter@296bfddb, org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter@22ab1b8a, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@54033a65, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@7dfec0bc, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@42734b71, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@3c8dea0b, org.springframework.security.web.session.SessionManagementFilter@6fe9c048, org.springframework.security.web.access.ExceptionTranslationFilter@526fc044, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@690e4b00]
2019-06-12 10:29:59.600  INFO 25207 --- [           main] o.s.s.web.DefaultSecurityFilterChain     : Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/iungo/*/**']]], [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@1978b0d5, org.springframework.security.web.context.SecurityContextPersistenceFilter@69a3bf40, org.springframework.security.web.header.HeaderWriterFilter@3186f8f5, org.springframework.security.web.authentication.logout.LogoutFilter@a4dcede, org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter@760c777d, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@2c731a16, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@2a341e3d, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@6556471b, org.springframework.security.web.session.SessionManagementFilter@467cd4b9, org.springframework.security.web.access.ExceptionTranslationFilter@3f3f554f, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@d0e4972]
2019-06-12 10:29:59.603  INFO 25207 --- [           main] o.s.s.web.DefaultSecurityFilterChain     : Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/oauth/authorize']]], [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@6cf3b3d7, org.springframework.security.web.context.SecurityContextPersistenceFilter@462f8fe9, org.springframework.security.web.header.HeaderWriterFilter@24f2608b, org.springframework.security.web.csrf.CsrfFilter@713497cd, org.springframework.security.web.authentication.logout.LogoutFilter@56193e3a, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@3c6fc4cd, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@b2e1df3, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@2e785b28, org.springframework.security.web.session.SessionManagementFilter@12a9e864, org.springframework.security.web.access.ExceptionTranslationFilter@4b762988]
2019-06-12 10:29:59.731  INFO 25207 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-06-12 10:29:59.902  INFO 25207 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2019-06-12 10:29:59.903  INFO 25207 --- [           main] nl.highway.iungomain.Application         : Started Application in 2.937 seconds (JVM running for 3.345)
2019-06-12 10:29:59.923  INFO 25207 --- [           main] o.h.h.i.QueryTranslatorFactoryInitiator  : HHH000397: Using ASTQueryTranslatorFactory
2019-06-12 10:30:12.550  INFO 25207 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2019-06-12 10:30:12.550  INFO 25207 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2019-06-12 10:30:12.554  INFO 25207 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 4 ms
2019-06-12 10:30:12.632  WARN 25207 --- [nio-8080-exec-1] o.s.s.c.bcrypt.BCryptPasswordEncoder     : Empty encoded password

您必须在configureGlobal方法中添加bCryptPasswordEncoder

@Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .userDetailsService(userDetailsService)
            .passwordEncoder(bCryptPasswordEncoder());
    }

我发现了问题。我使用的是SpringBoot2.1.4.RELEASE,但此设置仅适用于1.5.12.RELEASE。当然,降级不是很好的做法,所以我仍然会尝试让它与2.1.4一起工作。

我认为@ghazouanbadr的解决方案是正确的。尽管如此,我在我的实践项目中采用了不同的方法:

@EnableWebSecurity
@Configuration
public class WebSecurity extends WebSecurityConfigurerAdapter {
    @Autowired
    UserService userService;
    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

    public WebSecurity(UserService userService, BCryptPasswordEncoder bCryptPasswordEncoder) {
        this.userService = userService;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    } 

    @Override // Authorization
    protected void configure(HttpSecurity http) throws Exception {
        ...
    }

    @Override // Authentication
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userService(userService).passwordEncoder(bCryptPasswordEncoder);
   }
}

请注意,创建这个类时,我学习Java才一个月左右。我不太记得安全问题,所以我不该告诉你这是最好的方法。因为我记得曾经处理过同一个问题,所以我认为它可能会指引您正确的方向。

您尝试过基本身份验证吗?您能详细说明一下吗?您是否有以下方法:@Override public void configure(AuthorizationServerEndpoints配置器端点)在类扩展中:AuthorizationServerConfigurerAdapterYes,使用
.tokenStore(tokenStore()).accessTokenConverter(jwtTokenEnhancer()).authenticationManager(authManager)其中authManager只是
私有最终身份验证管理器authManager@Suwappertjes拥有一个样本可能会有所帮助。你能把一个样本发布到GitHub吗?我很乐意看一看。谢谢你的提示!我添加了这段代码,但不幸的是没有任何更改
@EnableWebSecurity
@Configuration
public class WebSecurity extends WebSecurityConfigurerAdapter {
    @Autowired
    UserService userService;
    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

    public WebSecurity(UserService userService, BCryptPasswordEncoder bCryptPasswordEncoder) {
        this.userService = userService;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    } 

    @Override // Authorization
    protected void configure(HttpSecurity http) throws Exception {
        ...
    }

    @Override // Authentication
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userService(userService).passwordEncoder(bCryptPasswordEncoder);
   }
}