Shiro异常java.lang.IllegalArgumentException: Odd number of characters解决方案

本文详细分析了Shiro中遇到的`java.lang.IllegalArgumentException: Odd number of characters`异常的原因,指出问题在于密码匹配不对应。重点检查了Shiro配置文件中的密码加密设置,并提醒在UserRealm部分的代码中,SimpleAuthenticationInfo构造函数中的密码应为数据库中的密文。同时,提供了MD5转换代码以帮助检查数据库中存储的密码是否正确加密。

根本原因:密码匹配不对应

本次错误:数据库的密码和加盐后的密码要一致。

根本原因:密码匹配不对应
1.首先先检查是否使用了加密,如果使用了加密方式,那么有可能就是你数据库中存储的密码是明文形式的密码,所以两者无法匹配。
因为我在shiro里面对密码 进行了MD5加密,所以这和我们一般的密码匹配还不一样。
首先先检查我们对于shiro的配置文件信息

<bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
        <!--声明加密算法-->
        <property name="hashAlgorithmName" value="md5"></property>
        <!--声明加密次数-->
        <property name="hashIterations" value="10"></property>
        <!--存储散列后的密码是否为16进制>
        <property name="storedCredentialsHexEncoded" value="true"></property>
    </bean>

    1
    2
    3
    4
    5
    6
    7
    8

这里主要及时对我们的密码加密进行相关的配置。
之后再看我们的UserRealm部分的代码:

 @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String loginName=authenticationToken.getPrincipal().toString();
        UserDao userDao=userService.getUserByLoginName(loginName);
        if(userDao==null) {
            throw new UnknownAccountException("账号不存在!");
        }
        if(userDao.getUsageState()==0){
            throw new LockedAccountException("账号已锁定!");
        }
        return new SimpleAuthenticationInfo(userDao.getLoginName(),userDao.getPassword(), ByteSource.Util.bytes(loginName),getName());//获取数据库中查到的用户的名称以及密码,之后通过用户名进行加盐加密,ByteSource.Util.bytes(loginName)即为盐值
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

代码中我们是没有问题的,但是我们也需要注意一点,就是SimpleAuthenticationInfo参数中的密码,这里必须要是我们从数据库中取出来的密码即密文形式的密码,如果是直接用的明文形式密码,那么也会报错这点一定要记好。
2. 其次就是既然是从数据库中取出密文形式的密码,那么就必须要保证我们数据库中存储的的确是密文形式的密码,所以我们必须要检查数据库。这里也就是博主错误的地方。
这里附上MD5转换的代码,大家可以通过这个来检测是不是我们所存储的密码。

import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;
import org.junit.Test;

public class PasswordSaltTest {
    @Test
    public void test() throws Exception {
        System.out.println(md5("123","username"));
    }

    public static final String md5(String password, String salt){
        //加密方式
        String hashAlgorithmName = "MD5";
        //盐:为了即使相同的密码不同的盐加密后的结果也不同
        ByteSource byteSalt = ByteSource.Util.bytes(salt);
        //密码
        Object source = password;
        //加密次数
        int hashIterations = 10;
        SimpleHash result = new SimpleHash(hashAlgorithmName, source, byteSalt, hashIterations);
        return result.toString();
    }

}

————————————————
版权声明:本文为优快云博主「萌萌哒的瓤瓤」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/lovely__RR/article/details/107764100

当你在使用Spring Boot和Shiro集成的时候,遇到`java.lang.NoClassDefFoundError: javax/servlet/Filter`这个错误,通常是因为缺少了Servlet API相关的依赖。Servlet API是Java Servlet规范的一部分,它定义了一些核心组件如Filter,用于Web应用程序处理请求。 解决这个问题的步骤通常是: 1. **添加依赖**:检查你的pom.xml文件或者build.gradle文件,确认已经包含了Servlet API的依赖。对于Maven,可以添加如下依赖: ```xml <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <!-- 或者最新的版本 --> <scope>provided</scope> <!-- Spring Boot默认会提供这层API,所以这里是提供的意思 --> </dependency> ``` 如果是Gradle,添加类似这样的: ```groovy implementation 'javax.servlet:javax.servlet-api:4.0.1' ``` 2. **配置Spring Boot**:由于Spring Boot会在运行时自动排除对已包含功能的第三方库的依赖,如果Servlet是作为Spring Boot自动包含的部分(即`web` starter),确保你不需要手动排除这一依赖。 3. **检查类路径**:确保你的项目构建过程中,Tomcat或Web服务器能够找到这个缺失的类,可能需要调整启动类或者配置文件中的类加载路径设置。 4. **重启应用**:最后,清理并重新启动你的Spring Boot应用,看看是否解决了问题。 如果你按照上述步骤仍然遇到问题,可能是其他环境变量设置错误或者有其他的类冲突,建议查看详细的日志以获取更多线索。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值