Spring Security 5:没有为 id“null"映射的 PasswordEncoder [英] Spring Security 5 : There is no PasswordEncoder mapped for the id "null"
问题描述
我正在从 Spring Boot 1.4.9 迁移到 Spring Boot 2.0 以及 Spring Security 5,我正在尝试通过 OAuth 2 进行身份验证.但我收到此错误:
<块引用>java.lang.IllegalArgumentException:没有为 idnull"映射的 PasswordEncoder
来自Spring Security 5,我知道了更改密码的存储格式.
在我当前的代码中,我将密码编码器 bean 创建为:
@Bean公共 BCryptPasswordEncoder passwordEncoder() {返回新的 BCryptPasswordEncoder();}
但是它给了我以下错误:
<块引用>编码后的密码看起来不像 BCrypt
所以我按照 Spring Security 5 文档到:
@Bean公共密码编码器密码编码器(){返回 PasswordEncoderFactories.createDelegatingPasswordEncoder();}
现在,如果我可以在数据库中看到密码,它将存储为
{bcrypt}$2a$10$LoV/3z36G86x6Gn101aekuz3q9d7yfBp3jFn7dzNN/AL5630FyUQ
第一个错误消失了,现在当我尝试进行身份验证时,出现以下错误:
<块引用>java.lang.IllegalArgumentException: 没有为 idnull"映射的 PasswordEncoder
为了解决这个问题,我尝试了以下来自 Stackoverflow 的所有问题:
这里有一个与我相似但没有回答的问题:
注意:我已经将加密密码存储在数据库中,因此无需在 UserDetailsService
中再次编码.
在他们建议您可以使用以下方法处理此异常的 Spring security 5 文档:
<块引用>DelegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(PasswordEncoder)
如果这是修复,那么我应该把它放在哪里?我试图把它放在 PasswordEncoder
bean 中,如下所示,但它不起作用:
DelegatingPasswordEncoder def = new DelegatingPasswordEncoder(idForEncode, encoders);def.setDefaultPasswordEncoderForMatches(passwordEncoder);
MyWebSecurity 类
@Configuration@启用网络安全公共类 SecurityConfiguration 扩展了 WebSecurityConfigurerAdapter {@自动连线私有 UserDetailsService userDetailsService;@豆角,扁豆公共密码编码器密码编码器(){返回 PasswordEncoderFactories.createDelegatingPasswordEncoder();}@自动连线public void configureGlobal(AuthenticationManagerBuilder auth) 抛出异常 {auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());}@覆盖公共无效配置(WebSecurity web)抛出异常{网络.忽略().antMatchers(HttpMethod.OPTIONS).antMatchers("/api/user/add");}@覆盖@豆角,扁豆公共 AuthenticationManager authenticationManagerBean() 抛出异常 {返回 super.authenticationManagerBean();}}
MyOauth2 配置
@Configuration@EnableAuthorizationServer受保护的静态类 AuthorizationServerConfiguration 扩展了 AuthorizationServerConfigurerAdapter {@豆角,扁豆公共令牌商店令牌商店(){返回新的 InMemoryTokenStore();}@自动连线@Qualifier("authenticationManagerBean")私有 AuthenticationManager authenticationManager;@豆角,扁豆公共 TokenEnhancer tokenEnhancer() {返回新的 CustomTokenEnhancer();}@豆角,扁豆公共 DefaultAccessTokenConverter accessTokenConverter() {返回新的 DefaultAccessTokenConverter();}@覆盖公共无效配置(AuthorizationServerEndpointsConfigurer 端点)抛出异常{端点.tokenStore(tokenStore()).tokenEnhancer(tokenEnhancer()).accessTokenConverter(accessTokenConverter()).authenticationManager(authenticationManager);}@覆盖公共无效配置(ClientDetailsServiceConfigurer 客户端)抛出异常 {客户.在记忆中().withClient("测试").scopes("读", "写").authorities(Roles.ADMIN.name(), Roles.USER.name()).authorizedGrantTypes("密码", "refresh_token").secret("秘密").accessTokenValiditySeconds(1800);}}
请指导我解决这个问题.我花了几个小时来解决这个问题,但无法解决.
在配置 ClientDetailsServiceConfigurer
时,还必须应用新的 密码存储格式到客户端密钥.
.secret("{noop}secret")
I am migrating from Spring Boot 1.4.9 to Spring Boot 2.0 and also to Spring Security 5 and I am trying to do authenticate via OAuth 2. But I am getting this error:
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null
From the documentation of Spring Security 5, I get to know that storage format for password is changed.
In my current code I have created my password encoder bean as:
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
However it was giving me below error:
Encoded password does not look like BCrypt
So I update the encoder as per the Spring Security 5 document to:
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
Now if I can see password in database it is storing as
{bcrypt}$2a$10$LoV/3z36G86x6Gn101aekuz3q9d7yfBp3jFn7dzNN/AL5630FyUQ
With that 1st error gone and now when I am trying to do authentication I am getting below error:
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null
To solve this issue I tried all the below questions from Stackoverflow:
Here is a question similar to mine but not answerd:
NOTE: I am already storing encrypted password in database so no need to encode again in UserDetailsService
.
In the Spring security 5 documentation they suggested you can handle this exception using:
DelegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(PasswordEncoder)
If this is the fix then where should I put it? I have tried to put it in PasswordEncoder
bean like below but it wasn't working:
DelegatingPasswordEncoder def = new DelegatingPasswordEncoder(idForEncode, encoders);
def.setDefaultPasswordEncoderForMatches(passwordEncoder);
MyWebSecurity class
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers(HttpMethod.OPTIONS)
.antMatchers("/api/user/add");
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
MyOauth2 Configuration
@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Bean
public TokenEnhancer tokenEnhancer() {
return new CustomTokenEnhancer();
}
@Bean
public DefaultAccessTokenConverter accessTokenConverter() {
return new DefaultAccessTokenConverter();
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints
.tokenStore(tokenStore())
.tokenEnhancer(tokenEnhancer())
.accessTokenConverter(accessTokenConverter())
.authenticationManager(authenticationManager);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("test")
.scopes("read", "write")
.authorities(Roles.ADMIN.name(), Roles.USER.name())
.authorizedGrantTypes("password", "refresh_token")
.secret("secret")
.accessTokenValiditySeconds(1800);
}
}
Please guide me with this issue. I have spend hours to fix this but not able to fix.
When you are configuring the ClientDetailsServiceConfigurer
, you have to also apply the new password storage format to the client secret.
.secret("{noop}secret")
这篇关于Spring Security 5:没有为 id“null"映射的 PasswordEncoder的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!