解决There is no PasswordEncoder mapped for the id “null“问题

springsecurity从4.2升级到5.0之后,做简单的登录,出现如下所示的错误:

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)

根据官方文档的资料和网上解决办法,需要做一些修改。

默认情况下与4.2版本不同的是,springsecurity5.0密码加密方式采用了bcrypt的方式,而且密码直接配置在xml文件中,不光是需要使用BCryptPasswordEncoder来加密,还需要指定一个encodingId,如果不指定,就会报出如题所示的错误。

我们可以看看PasswordEncoderFactories.createDelegatingPasswordEncoder()方法:

这就是为什么说默认情况下使用的bcrypt方式加密。

知道了用什么方式,我们就可以来改进了。

1、密码不加密,和springsecurity4.2一样,使用明文密码,那就需要配置密码验证方式为noop,配置如下。

<beans:bean id="passwordEncoder" class="org.springframework.security.crypto.password.NoOpPasswordEncoder"></beans:bean>

在spring-security.xml配置文件中配置以上bean即可。

密码配置如下:

<user name="admin" password="123456" authorities="ROLE_USER"/>

这样,默认密码就不需要进行加密,原样传入,原样匹配。这种配置方式密码前面,不需要加上{noop} 

2、使用默认的密码加密方式,需要改动密码,并且密码格式如下:

{bcrypt}$2a$10$rY/0dflGbwW6L1yt4RVA4OH8aocD7tvMHoChyKY/XtS4DXKr.JbTC

在通过bcrypt方式加密之后的密文,前面加上{bcrypt}。

这里另外介绍两种方式来通过bcrypt方式加密,直接上源码:

package com.xxx.security.test;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;

public class PasswordEncoder {
    public static void main(String[] args) {
        org.springframework.security.crypto.password.PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
        String password = "123456";
        String password2 = encoder.encode(password);
        System.out.println(password2);
        System.out.println(encoder.matches(password, password2));
        BCryptPasswordEncoder encoder2 = new BCryptPasswordEncoder();
        String password3 = encoder2.encode(password);
        System.out.println(password3);
        System.out.println(encoder2.matches(password, password3));
    }  
}

运行以上代码,打印结果如下:

 眼尖的你,可能一下子就发现了一个小问题,通过bcrypt方式加密的密文,除了{bcrypt}外两次结果不一样,怎么会这样?

和以往加密方式不同的是,springsecurity5.0以上版本对bcrypt加密方式进行了随机数处理,所以每次产生的结果都不一样。不管是哪种方式,我们如果使用默认的加密方式,就需要在xml中配置密码为如下的样子。记得前面有{bcrypt}。

{bcrypt}$2a$10$rY/0dflGbwW6L1yt4RVA4OH8aocD7tvMHoChyKY/XtS4DXKr.JbTC

报错的意思是说我们没有指定一个encodingId,最终在encoders map中没有匹配到encodingId。

如果我们需要使用MD5方式加密,我们就需要指定如下所示的密码:

{MD5}{pwegM3ORx1OzOc4eFzVztSPdeZit0BZPWTA5JB1Juc0=}dda279a014895996e55957976ec4cd36

同理,如果我们需要像springsecurity4.2那样,密码明文,我们可以这样配置:

<user name=”admin” password=”{noop}123456″ authorities=”ROLE_USER”/>

也无需像第一种方式那样在配置文件中增加NoOpPasswordEncoder的配置了。

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值