没有为 id“null"映射的 PasswordEncoder在春季安全 [英] There is no PasswordEncoder mapped for the id "null" in Spring Security
问题描述
我正在从 Spring Boot 1.5.12 迁移到 Spring Boot 2.0 以及 Spring Security 5,并且我正在尝试通过 OAuth 2 进行身份验证.但即使在使用委托 {noop} 后我仍然收到此错误:
java.lang.IllegalArgumentException: 没有为 idnull"映射的 PasswordEncoder
这是我的代码:
安全配置
public class SecurityConfig extends WebSecurityConfigurerAdapter {@自动连线private CustomUserDetailsService userDetailsService;@豆public PasswordEncoder passwordEncoder() {返回 PasswordEncoderFactories.createDelegatingPasswordEncoder();}公共安全配置(){超级();SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);}@覆盖protected void configure(final HttpSecurity http) 抛出异常 {http.cors().and().csrf().disable().exceptionHandling().and().authorizeRequests().antMatchers("/api/v1/**").authenticated().and().httpBasic();}@覆盖public void configure(final WebSecurity web) 抛出异常 {web.ignoring().antMatchers(/v2/api-docs"、/configuration/ui"、/swagger-resources"、/configuration/security"、/webjars/**"、/swagger-resources/configuration/ui",/swagger-resources/configuration/security",/swagger-ui.html"、/admin11/*"、/*.html"、/*.jsp"、/favicon.ico"、//*.html";, "//*.css", "//*.js","/admin11/monitoring","/proxy.jsp");}@覆盖protected void configure(final AuthenticationManagerBuilder auth) 抛出异常 {auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());}@豆@覆盖公共 AuthenticationManager authenticationManagerBean() 抛出异常 {返回 super.authenticationManagerBean();}}
Oauth2AuthorizationServerConfig
public class Oauth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {@自动连线@Qualifier(authenticationManagerBean")私有 AuthenticationManager authenticationManager;@自动连线private CustomUserDetailsService userDetailsService;@自动连线私有 JdbcTokenStore jdbcTokenStore;@豆公共令牌商店令牌商店(){返回 jdbcTokenStore;}@豆公共 JwtAccessTokenConverter accessTokenConverter() {CustomTokenEnhancer 转换器 = new CustomTokenEnhancer();Converter.setSigningKey(secret_api");返回转换器;}@覆盖公共无效配置(最终 AuthorizationServerEndpointsConfigurer 端点)抛出异常 {endpoints.tokenStore(tokenStore()).accessTokenConverter(accessTokenConverter()).authenticationManager(authenticationManager).userDetailsService(userDetailsService).pathMapping("/oauth/token", "/api/v1/oauth/token");}@覆盖公共无效配置(ClientDetailsServiceConfigurer 客户端)抛出异常 {clients.inMemory().withClient("app").secret("{noop}secret").authorizedGrantTypes("password", "authorization_code").scopes("read", "write").autoApprove(true).accessTokenValiditySeconds(0);}@覆盖public void configure(final AuthorizationServerSecurityConfigurer oauthServer) 抛出异常 {oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");}@豆公共 DefaultTokenServices defaultTokenServices() {DefaultTokenServices defaultTokenServices = new DefaultTokenServices();defaultTokenServices.setTokenStore(tokenStore());返回 defaultTokenServices;}}
自定义用户详细信息服务
公共接口 CustomUserDetailsService 扩展 UserDetailsService {UserDetails getByMsisdn(String msisdn);void initDummyUsers();}
为了解决这个问题,我尝试了 Stackoverflow 中的以下问题:
Spring Boot PasswordEncoder 错误
存储的密码之一出现以下错误没有密码存储格式中描述的 ID.
java.lang.IllegalArgumentException: 没有映射的 PasswordEncoder对于 id null"在 org.springframework.security.crypto.password.DelegatingPasswordEncoder$UnmappedIdPasswordEncoder.matches(DelegatingPasswordEncoder.java:233)在 org.springframework.security.crypto.password.DelegatingPasswordEncoder.matches(DelegatingPasswordEncoder.java:196)
<块引用>
解决错误的最简单方法是显式切换到提供密码编码的 PasswordEncoder.该解决它的最简单方法是弄清楚您的密码如何当前正在存储并明确提供正确的密码编码器.
如果您从 Spring Security 4.2.x 迁移,您可以恢复到通过暴露 NoOpPasswordEncoder bean 以前的行为.
所以你应该能够通过显式提供 PasswordEncoder
//记住,这是不好的做法@豆public PasswordEncoder passwordEncoder() {返回 NoOpPasswordEncoder.getInstance();}
或者更好地提供一个 自定义密码编码器委托人:
String idForEncode = "bcrypt";映射编码器 = new HashMap<>();encodings.put(idForEncode, new BCryptPasswordEncoder());encodings.put(noop", NoOpPasswordEncoder.getInstance());encodings.put(pbkdf2", new Pbkdf2PasswordEncoder());encodings.put(scrypt", new SCryptPasswordEncoder());encodings.put(sha256", new StandardPasswordEncoder());PasswordEncoder passwordEncoder =新的委托密码编码器(idForEncode,编码器);
全部取自 关于密码编码的官方春季安全文档.
I am migrating from Spring Boot 1.5.12 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 even after using delegate {noop}:
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null
Here is my code :
SecurityConfig
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService userDetailsService;
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
public SecurityConfig() {
super();
SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().exceptionHandling().and().authorizeRequests()
.antMatchers("/api/v1/**")
.authenticated().and().httpBasic();
}
@Override
public void configure(final WebSecurity web) throws Exception {
web.ignoring().antMatchers(
"/v2/api-docs","/configuration/ui","/swagger-resources", "/configuration/security", "/webjars/**",
"/swagger-resources/configuration/ui","/swagger-resources/configuration/security",
"/swagger-ui.html", "/admin11/*", "/*.html", "/*.jsp", "/favicon.ico", "//*.html", "//*.css", "//*.js",
"/admin11/monitoring","/proxy.jsp");
}
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
Oauth2AuthorizationServerConfig
public class Oauth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Autowired
private CustomUserDetailsService userDetailsService;
@Autowired
private JdbcTokenStore jdbcTokenStore;
@Bean
public TokenStore tokenStore() {
return jdbcTokenStore;
}
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
CustomTokenEnhancer converter = new CustomTokenEnhancer();
converter.setSigningKey("secret_api");
return converter;
}
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore())
.accessTokenConverter(accessTokenConverter())
.authenticationManager(authenticationManager)
.userDetailsService(userDetailsService)
.pathMapping("/oauth/token", "/api/v1/oauth/token");
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("app").secret("{noop}secret")
.authorizedGrantTypes("password", "authorization_code").scopes("read", "write")
.autoApprove(true).accessTokenValiditySeconds(0);
}
@Override
public void configure(final AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
}
@Bean
public DefaultTokenServices defaultTokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
return defaultTokenServices;
}
}
CustomUserDetailsService
public interface CustomUserDetailsService extends UserDetailsService {
UserDetails getByMsisdn(String msisdn);
void initDummyUsers();
}
To solve this issue I tried the below questions from Stackoverflow:
Spring Boot PasswordEncoder Error
The Spring Security documentation is addressing your exact problem.
The following error occurs when one of the passwords that are stored has no id as described in Password Storage Format.
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped
for the id "null"
at org.springframework.security.crypto.password.DelegatingPasswordEncoder$UnmappedIdPasswordEncoder.matches(DelegatingPasswordEncoder.java:233)
at org.springframework.security.crypto.password.DelegatingPasswordEncoder.matches(DelegatingPasswordEncoder.java:196)
The easiest way to resolve the error is to switch to explicitly provide the PasswordEncoder that you passwords are encoded with. The easiest way to resolve it is to figure out how your passwords are currently being stored and explicitly provide the correct PasswordEncoder.
If you are migrating from Spring Security 4.2.x you can revert to the previous behavior by exposing a NoOpPasswordEncoder bean.
So you should be able to fix this by explicitly providing the PasswordEncoder
// remember, its bad practice
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
Or even better supply a custom defined password encoder delegator:
String idForEncode = "bcrypt";
Map encoders = new HashMap<>();
encoders.put(idForEncode, new BCryptPasswordEncoder());
encoders.put("noop", NoOpPasswordEncoder.getInstance());
encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
encoders.put("scrypt", new SCryptPasswordEncoder());
encoders.put("sha256", new StandardPasswordEncoder());
PasswordEncoder passwordEncoder =
new DelegatingPasswordEncoder(idForEncode, encoders);
All taken from the official spring security docs on password encoding.
这篇关于没有为 id“null"映射的 PasswordEncoder在春季安全的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!