java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id “null“ 产生原因

it2022-12-27  42

在做接口拦截器的时候自定义了一个配置类,但是运行在控制台上产生了java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null" 的问题。这个问题主要是依赖SpringBoot2.x整合Security5所引发的问题。现在idea中找到了DelegatingPasswordEncoder类,在这个类中包含了一个私有类UnmappedIdPasswordEncoder,是由于mathes方法导致的这个问题的发生。具体源码如下:

@Override public boolean matches(CharSequence rawPassword, String prefixEncodedPassword) { String id = extractId(prefixEncodedPassword); throw new IllegalArgumentException("There is no PasswordEncoder mapped for the id \"" + id + "\""); }

 

具体在调用的过程中是如何导致成这样的结果。根据以下源码我们通过该私有类它新建了一个defaultPasswordEncoderForMathches.朝着这样的思路走下去,去寻找他在何时有调用matches的情况。

private PasswordEncoder defaultPasswordEncoderForMatches = new UnmappedIdPasswordEncoder();

果然在DelegatingPasswordEncoder类中找到了对应的matches方法,DelegatingPasswordEncoder因为是实现的PasswordEncoder接口,所以在运行过程中重写了matches方法,在方法matches中又调用私有类对象defaultPasswordEncoderForMathches的matches方法。观看springboot官方文档可以看到密码的存储形式是这样的。(springboot官方文档地址https://docs.spring.io/spring-security/site/docs/5.0.2.RELEASE/reference/htmlsingle/#troubleshooting)

在matches中调用extractid方法没有提取出来相应的id,导致delegate为空才导致异常的抛出。

@Override public boolean matches(CharSequence rawPassword, String prefixEncodedPassword) { if (rawPassword == null && prefixEncodedPassword == null) { return true; } String id = extractId(prefixEncodedPassword); PasswordEncoder delegate = this.idToPasswordEncoder.get(id); if (delegate == null) { return this.defaultPasswordEncoderForMatches .matches(rawPassword, prefixEncodedPassword); } String encodedPassword = extractEncodedPassword(prefixEncodedPassword); return delegate.matches(rawPassword, encodedPassword); }

所以解决的方法就是重新新建一个类重新实现PasswordEncoder接口,在这个类中重写encode,matches方法,将参数转为string形式即可。然后在自定义的配置类中将DelegatingPasswordEncoder转为新建类名即可。

最新回复(0)