There is no PasswordEncoder mapped for the id "null" at org.springframework.security.crypto.解决办法

2019年07月27日 23:20:10 ShiYaXin_HarbourCity 阅读数 2 标签: 安全权限认证 更多
个人分类: 安全
环境/问题概述:

在项目构建的过程中,根据需求进行了系统升级,包括硬件和软件环境,项目开发使用的 Spring Boot 进行的,这次升级直接从1.5.2 直接升级为了2.0.3;
在包更正完成后,启动项目测试,遇到不能登录系统的问题,异常信息如下:

java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id “null”

at org.springframework.security.crypto.password.DelegatingPasswordEncoder U n m a p p e d I d P a s s w o r d E n c o d e r . m a t c h e s ( D e l e g a t i n g P a s s w o r d E n c o d e r . j a v a : 238 )   [ s p r i n g − s e c u r i t y − c o r e − 5.0.7. R E L E A S E . j a r : 5.0.7. R E L E A S E ] a t o r g . s p r i n g f r a m e w o r k . s e c u r i t y . c r y p t o . p a s s w o r d . D e l e g a t i n g P a s s w o r d E n c o d e r . m a t c h e s ( D e l e g a t i n g P a s s w o r d E n c o d e r . j a v a : 198 )   [ s p r i n g − s e c u r i t y − c o r e − 5.0.7. R E L E A S E . j a r : 5.0.7. R E L E A S E ] a t o r g . s p r i n g f r a m e w o r k . s e c u r i t y . c o n f i g . a n n o t a t i o n . w e b . c o n f i g u r a t i o n . W e b S e c u r i t y C o n f i g u r e r A d a p t e r UnmappedIdPasswordEncoder.matches(DelegatingPasswordEncoder.java:238) ~[spring-security-core-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.security.crypto.password.DelegatingPasswordEncoder.matches(DelegatingPasswordEncoder.java:198) ~[spring-security-core-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter UnmappedIdPasswordEncoder.matches(DelegatingPasswordEncoder.java:238) [springsecuritycore5.0.7.RELEASE.jar:5.0.7.RELEASE]atorg.springframework.security.crypto.password.DelegatingPasswordEncoder.matches(DelegatingPasswordEncoder.java:198) [springsecuritycore5.0.7.RELEASE.jar:5.0.7.RELEASE]atorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapterLazyPasswordEncoder.matches(WebSecurityConfigurerAdapter.java:593) ~[spring-security-config-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.security.authentication.dao.DaoAuthenticationProvider.additionalAuthenticationChecks(DaoAuthenticationProvider.java:86) ~[spring-security-core-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:166) ~[spring-security-core-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174) ~[spring-security-core-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199) ~[spring-security-core-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94) ~[spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) ~[spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.security.web.FilterChainProxy V i r t u a l F i l t e r C h a i n . d o F i l t e r ( F i l t e r C h a i n P r o x y . j a v a : 334 )   [ s p r i n g − s e c u r i t y − w e b − 5.0.7. R E L E A S E . j a r : 5.0.7. R E L E A S E ] a t o r g . s p r i n g f r a m e w o r k . s e c u r i t y . w e b . a u t h e n t i c a t i o n . l o g o u t . L o g o u t F i l t e r . d o F i l t e r ( L o g o u t F i l t e r . j a v a : 116 )   [ s p r i n g − s e c u r i t y − w e b − 5.0.7. R E L E A S E . j a r : 5.0.7. R E L E A S E ] a t o r g . s p r i n g f r a m e w o r k . s e c u r i t y . w e b . F i l t e r C h a i n P r o x y VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) ~[spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.security.web.FilterChainProxy VirtualFilterChain.doFilter(FilterChainProxy.java:334) [springsecurityweb5.0.7.RELEASE.jar:5.0.7.RELEASE]atorg.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) [springsecurityweb5.0.7.RELEASE.jar:5.0.7.RELEASE]atorg.springframework.security.web.FilterChainProxyVirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:124) ~[spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.FilterChainProxy V i r t u a l F i l t e r C h a i n . d o F i l t e r ( F i l t e r C h a i n P r o x y . j a v a : 334 )   [ s p r i n g − s e c u r i t y − w e b − 5.0.7. R E L E A S E . j a r : 5.0.7. R E L E A S E ] a t o r g . s p r i n g f r a m e w o r k . s e c u r i t y . w e b . h e a d e r . H e a d e r W r i t e r F i l t e r . d o F i l t e r I n t e r n a l ( H e a d e r W r i t e r F i l t e r . j a v a : 66 )   [ s p r i n g − s e c u r i t y − w e b − 5.0.7. R E L E A S E . j a r : 5.0.7. R E L E A S E ] a t o r g . s p r i n g f r a m e w o r k . w e b . f i l t e r . O n c e P e r R e q u e s t F i l t e r . d o F i l t e r ( O n c e P e r R e q u e s t F i l t e r . j a v a : 107 )   [ s p r i n g − w e b − 5.0.8. R E L E A S E . j a r : 5.0.8. R E L E A S E ] a t o r g . s p r i n g f r a m e w o r k . s e c u r i t y . w e b . F i l t e r C h a i n P r o x y VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66) ~[spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE] at org.springframework.security.web.FilterChainProxy VirtualFilterChain.doFilter(FilterChainProxy.java:334) [springsecurityweb5.0.7.RELEASE.jar:5.0.7.RELEASE]atorg.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66) [springsecurityweb5.0.7.RELEASE.jar:5.0.7.RELEASE]atorg.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [springweb5.0.8.RELEASE.jar:5.0.8.RELEASE]atorg.springframework.security.web.FilterChainProxyVirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) ~[spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.security.web.FilterChainProxy V i r t u a l F i l t e r C h a i n . d o F i l t e r ( F i l t e r C h a i n P r o x y . j a v a : 334 )   [ s p r i n g − s e c u r i t y − w e b − 5.0.7. R E L E A S E . j a r : 5.0.7. R E L E A S E ] a t o r g . s p r i n g f r a m e w o r k . s e c u r i t y . w e b . c o n t e x t . r e q u e s t . a s y n c . W e b A s y n c M a n a g e r I n t e g r a t i o n F i l t e r . d o F i l t e r I n t e r n a l ( W e b A s y n c M a n a g e r I n t e g r a t i o n F i l t e r . j a v a : 56 )   [ s p r i n g − s e c u r i t y − w e b − 5.0.7. R E L E A S E . j a r : 5.0.7. R E L E A S E ] a t o r g . s p r i n g f r a m e w o r k . w e b . f i l t e r . O n c e P e r R e q u e s t F i l t e r . d o F i l t e r ( O n c e P e r R e q u e s t F i l t e r . j a v a : 107 )   [ s p r i n g − w e b − 5.0.8. R E L E A S E . j a r : 5.0.8. R E L E A S E ] a t o r g . s p r i n g f r a m e w o r k . s e c u r i t y . w e b . F i l t e r C h a i n P r o x y VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) ~[spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE] at org.springframework.security.web.FilterChainProxy VirtualFilterChain.doFilter(FilterChainProxy.java:334) [springsecurityweb5.0.7.RELEASE.jar:5.0.7.RELEASE]atorg.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) [springsecurityweb5.0.7.RELEASE.jar:5.0.7.RELEASE]atorg.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [springweb5.0.8.RELEASE.jar:5.0.8.RELEASE]atorg.springframework.security.web.FilterChainProxyVirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) ~[spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) ~[spring-security-web-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) ~[tomcat-embed-core-8.5.32.jar:8.5.32]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.32.jar:8.5.32]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493) [tomcat-embed-core-8.5.32.jar:8.5.32]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.32.jar:8.5.32]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.32.jar:8.5.32]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.32.jar:8.5.32]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.32.jar:8.5.32]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800) [tomcat-embed-core-8.5.32.jar:8.5.32]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.32.jar:8.5.32]
at org.apache.coyote.AbstractProtocol C o n n e c t i o n H a n d l e r . p r o c e s s ( A b s t r a c t P r o t o c o l . j a v a : 800 ) [ t o m c a t − e m b e d − c o r e − 8.5.32. j a r : 8.5.32 ] a t o r g . a p a c h e . t o m c a t . u t i l . n e t . N i o E n d p o i n t ConnectionHandler.process(AbstractProtocol.java:800) [tomcat-embed-core-8.5.32.jar:8.5.32] at org.apache.tomcat.util.net.NioEndpoint ConnectionHandler.process(AbstractProtocol.java:800)[tomcatembedcore8.5.32.jar:8.5.32]atorg.apache.tomcat.util.net.NioEndpointSocketProcessor.doRun(NioEndpoint.java:1471) [tomcat-embed-core-8.5.32.jar:8.5.32]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.32.jar:8.5.32]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_40]
at java.util.concurrent.ThreadPoolExecutor W o r k e r . r u n ( T h r e a d P o o l E x e c u t o r . j a v a : 617 ) [ n a : 1.8. 0 4 0 ] a t o r g . a p a c h e . t o m c a t . u t i l . t h r e a d s . T a s k T h r e a d Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_40] at org.apache.tomcat.util.threads.TaskThread Worker.run(ThreadPoolExecutor.java:617)[na:1.8.040]atorg.apache.tomcat.util.threads.TaskThreadWrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.32.jar:8.5.32]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_40]

如下图所示:

解决办法:

本次解决方法通过阅读 Spring Security 的官方文档 + 阅读了一些源码,最终把问题给解决了,由于项目涉密,这儿只给你个简单实例,以阐述问题的解决办法。
1、首先从官方文档入手,在Spring 官网找到 security 项目(https://spring.io/projects),如下图:

2、由于在Spring Boot 2.0.3 中依赖的 Security 的版本为 5.0.7 所以在这儿只查看 Spring Security-5.0.7 的,如下图:
项目依赖版本:

所以需要查看对应的 Spring Security-5.0.7 的文档,如下图:

点击进入,在该文档的第 10 节的第 3 小姐中明确的阐述导致该问题的根本原因有,部分截图如下(如果仔细阅读,这儿已给出了具体的章节,可以自行前往查阅):

关于 Spring Security 5.0.X 的说明:
在Spring Security 5.0之前,PasswordEncoder 的默认值为 NoOpPasswordEncoder 既表示为纯文本密码,在实际的开发过程中 PasswordEncoder 大多数都会设值为 BCryptPasswordEncoder ,但是这样会导致几个问题:
1、在应用程序中使用 BCryptPasswordEncoder 编码方式编码后的密码,很难轻松的迁移;
2、密码存储后,会再次被更改;
3、作为一个应用中的安全框架,Spring Security 不能频繁地进行中断更改;

在 Spring Security 5.0.x 以后,密码的一般格式为:{ID} encodedPassword ,ID 主要用于查找 PasswordEncoder 对应的编码标识符,并且encodedPassword 是所选的原始编码密码 PasswordEncoder。ID 必须书写在密码的前面,开始用{,和 结束 }。如果 ID 找不到,ID 则为null。例如,在相关的源码中,我找到了 Spring Security 定义的不同的编码方式的列表 ID。所有原始密码都是“ password ”。

源码中定义的全部编码方式的列表 ID 如下图:

解决办法的示例:
更正前的用户认证规则:

// 自定义配置认证规则

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
            .withUser("zhangsan").password("12345").roles("SuperAdmin")
            .and()
            .withUser("lisi").password("12345").roles("Admin")
            .and()
            .withUser("wangwu").password("12345").roles("Employee");

}

新建一个 PasswordEncoder 并实现 PasswordEncoder 接口,重新 里面的两个方法,并定义为明文的加密方式,具体内容如下:

public class CustomPasswordEncoder implements PasswordEncoder {

@Override
public String encode(CharSequence charSequence) {
    return charSequence.toString();
}

@Override
public boolean matches(CharSequence charSequence, String s) {
    return s.equals(charSequence.toString());
}

}

在用户认证规则中添加自定义的 PasswordEncoder 实例,具体内容如下:

// 自定义配置认证规则

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
            .withUser("zhangsan").password("12345").roles("SuperAdmin")
            .and()
            .withUser("lisi").password("12345").roles("Admin")
            .and()
            .withUser("wangwu").password("12345").roles("Employee")
            .and()
            .passwordEncoder(new CustomPasswordEncoder())

}

在再去进行登录验证,就可以实现了,关于更多的问题,推荐去官方文档进行查询/或者查阅相关的源码(里面后明确的标注哦!)。

好了,关于 There is no PasswordEncoder mapped for the id “null” 的解决办法 就写到这儿了,如果还有问题也可以给我留言哦,我会一一详细的解答的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值