![](/img/trans.png)
[英]Spring Security 5 : There is no PasswordEncoder mapped for the id "null"
[英]There is no PasswordEncoder mapped for the id “null” in Spring Security
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:沒有為 id “null”映射 PasswordEncoder
這是我的代碼:
安全配置
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();
}
為了解決這個問題,我嘗試了 Stackoverflow 的以下問題:
當存儲的密碼之一沒有密碼存儲格式中所述的 id 時,會發生以下錯誤。
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)
解決該錯誤的最簡單方法是切換為顯式提供密碼編碼所用的 PasswordEncoder。 解決它的最簡單方法是弄清楚您的密碼當前是如何存儲的,並明確提供正確的 PasswordEncoder。
如果您從 Spring Security 4.2.x 遷移,您可以通過公開 NoOpPasswordEncoder bean 恢復到以前的行為。
因此,您應該能夠通過顯式提供PasswordEncoder
來解決此問題
// remember, its bad practice
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
甚至更好地提供自定義的密碼編碼器委托:
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);
全部取自官方 spring 密碼編碼安全文檔。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.