【问题标题】:Encrypting InMemoryAuthentication passwords with Bcrypt使用 Bcrypt 加密 InMemoryAuthentication 密码
【发布时间】:2018-08-25 00:32:23
【问题描述】:

在我对 UserDetailsS​​ervice 的自定义实现使用 Bcrypt 之前,我首先想看看我是否可以在内存数据库中使用它。

package com.patrick.Security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private UserDetailsService userDetailsService;


    @Autowired
    public WebSecurityConfig(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers(HttpMethod.POST, "/login").permitAll()
                .antMatchers(HttpMethod.POST, "/users").hasAuthority("ADMIN")
                .antMatchers(HttpMethod.POST, "/shifts").hasAnyAuthority("ADMIN", "SUPERVISOR")
                .anyRequest().authenticated()
                .and()
                .addFilter(new AuthenticationFilter(authenticationManager()))
                .addFilter(new AuthorizationFilter(authenticationManager()));
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().passwordEncoder(passwordEncoder())
                .withUser("admin").password("password").roles("ADMIN");
    }

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

创建/公开 PasswordEncoder bean 时会弹出此警告,最终阻止我访问登录路径:

o.s.s.c.bcrypt.BCryptPasswordEncoder     : Encoded password does not look like BCrypt

添加已弃用的 NoOpPasswordEncoder 将暂时解决问题,但显然不会对密码进行编码:

@SuppressWarnings("deprecation")
@Bean
public static NoOpPasswordEncoder passwordEncoder() {
return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
}

添加Bcrypt的正确方法是什么?

【问题讨论】:

    标签: spring spring-security


    【解决方案1】:

    创建/公开 PasswordEncoder bean 时会弹出此警告 这最终阻止了我访问登录路径:

    o.s.s.c.bcrypt.BCryptPasswordEncoder     : Encoded password does not look like BCrypt
    

    这是因为您提供的密码未使用 BCrypt 编码。与其直接传递"password" 作为密码,不如先对其进行编码。

    出于测试目的,一个简单的方法是获取您的密码编码器并在您的配置方法中对其进行编码,如下所示

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        String password = passwordEncoder().encode("password");
        auth.inMemoryAuthentication().withUser("admin").password(password).roles("ADMIN");
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    

    【讨论】:

    • 啊,是的。现在看来很明显。我的印象是它是自动完成的。
    【解决方案2】:

    使用Spring Security 5,您可以在密码前加上所选PasswordEncoderid。如果你想使用普通密码,那么只需使用{noop} 前缀,这会将密码编码器委托给NoOpPasswordEncoder

    示例代码:

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
       auth.inMemoryAuthentication()
              .withUser("admin").password("{noop}password").roles("ADMIN");
    }
    

    【讨论】:

    • 使用 Spring Boot 5.1,此解决方案会导致性能下降(每次检查密码时 > 100ms),因为由于某种原因 BCryptPasswordEncoder 被初始化。希望以后能修复。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-31
    • 1970-01-01
    • 1970-01-01
    • 2019-02-10
    相关资源
    最近更新 更多