在我在UserDetailsService的自定义实现上使用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的正确方法是什么?
答案 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");
}