使用Bcrypt加密InMemoryAuthentication密码

时间:2018-03-16 02:32:13

标签: spring spring-security

在我在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

添加Deprecated NoOpPasswordEncoder会暂时解决问题,但显然不会对密码进行编码:

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

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

2 个答案:

答案 0 :(得分:10)

  

通过创建/公开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();
}

答案 1 :(得分:3)

使用Spring Security 5,您可以为所选id中的PasswordEncoder加上密码前缀。如果要使用普通密码,则只需使用{noop}前缀,这会将密码编码器委派给NoOpPasswordEncoder

示例代码:

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