Spring Security There is no PasswordEncoder mapped for the id "|8月更文挑战

421 阅读1分钟

这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战

Spring Security There is no PasswordEncoder mapped for the id "null"

 java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"\
     at org.springframework.security.crypto.password.DelegatingPasswordEncoder$UnmappedIdPasswordEncoder.matches(DelegatingPasswordEncoder.java:238)\
at org.springframework.security.crypto.password.DelegatingPasswordEncoder.matches(DelegatingPasswordEncoder.java:198)\
at org.springframework.security.authentication.dao.DaoAuthenticationProvider.additionalAuthenticationChecks(DaoAuthenticationProvider.java:86)\
at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:166)\
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174)

at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199)

...

官网解释:

docs.spring.io/spring-secu…

Troubleshooting

The following error occurs when one of the passwords that are stored has no id as described in the section called “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. For example, if you are using Java Configuration, you can create a configuration that looks like:


java 配置:

 @Bean
public static NoOpPasswordEncoder passwordEncoder() {
    return NoOpPasswordEncoder.getInstance();
}
public static NoOpPasswordEncoder passwordEncoder() {
    return NoOpPasswordEncoder.getInstance();
}

xml 配置:(if you are using XML configuration, you can expose a PasswordEncoder with the id passwordEncoder:)

<b:bean id="passwordEncoder" class="org.springframework.security.crypto.password.NoOpPasswordEncoder"

factory-method="getInstance"/>

xml完整配置:

注意红色位置: <security:password-encoder ref="passwordEncoder"/>

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:security="http://www.springframework.org/schema/security"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      http://www.springframework.org/schema/security
      http://www.springframework.org/schema/security/spring-security.xsd">

    <!-- use-expressions:Spring 表达式语言配置访问控制 -->
    <security:http auto-config="true" use-expressions="false">
        <!-- 配置权限拦截,访问所有url,都需要用户登录,且拥有ROLE_USER权限 -->
        <security:intercept-url pattern="/**" access="ROLE_USER"/>

    </security:http>

    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider>
            <security:password-encoder ref="passwordEncoder"/>
            <!-- 配置默认用户,用户名:admin 密码:123456 拥有权限:ROLE_USER -->
            <security:user-service>
                <security:user name="admin" password="123456"
                               authorities="ROLE_USER"/>
            </security:user-service>
        </security:authentication-provider>

    </security:authentication-manager>
    <bean id="passwordEncoder"
          class="org.springframework.security.crypto.password.NoOpPasswordEncoder" factory-method="getInstance"/>
</beans>