Shiro異常java.lang.IllegalArgumentException: Odd number of characters的解決方案

最近在做前後端分離,登錄認證部分用到了Shiro,配置MD5加鹽加密後,在登錄的時候拋出的以下異常:

java.lang.IllegalArgumentException: Odd number of characters.
    at org.apache.shiro.codec.Hex.decode(Hex.java:128) ~[shiro-core-1.3.2.jar:1.3.2]
    at org.apache.shiro.codec.Hex.decode(Hex.java:107) ~[shiro-core-1.3.2.jar:1.3.2]
    at org.apache.shiro.codec.Hex.decode(Hex.java:95) ~[shiro-core-1.3.2.jar:1.3.2]
    at org.apache.shiro.authc.credential.HashedCredentialsMatcher.getCredentials(HashedCredentialsMatcher.java:353) ~[shiro-core-1.3.2.jar:1.3.2]
    at org.apache.shiro.authc.credential.HashedCredentialsMatcher.doCredentialsMatch(HashedCredentialsMatcher.java:380) ~[shiro-core-1.3.2.jar:1.3.2]
    at org.apache.shiro.realm.AuthenticatingRealm.assertCredentialsMatch(AuthenticatingRealm.java:597) ~[shiro-core-1.3.2.jar:1.3.2]
 ...

對應Realm的代碼:

public class CustomRealm extends AuthorizingRealm {
    @Autowired
    UserMapper usermapper;

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
            throws AuthenticationException {

        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String username = String.valueOf(token.getUsername());
        String password = String.valueOf(token.getPassword());
        // 從數據庫獲取對應用戶名的用戶
        User user = usermapper.findByUsername(username);
        if (user == null) {
            throw new AccountException("不存在此用戶");
        }
        // 獲取鹽值,即用戶名
        ByteSource salt = ByteSource.Util.bytes(username);
        return new SimpleAuthenticationInfo(token.getPrincipal(), password, salt, getName());
    }
}

錯誤就在最後一句代碼:

return new SimpleAuthenticationInfo(token.getPrincipal(), password, salt, getName());

在這裏直接把明文密碼當成參數傳入了構造器

解決方案:將MD5加密後的密碼傳入構造器

修改後代碼:

public class CustomRealm extends AuthorizingRealm {
    @Autowired
    UserMapper usermapper;

    /**
     * 獲取身份驗證信息 Shiro中,最終是通過 Realm 來獲取應用程序中的用戶、角色及權限信息的。
     *
     * @param authenticationToken
     *            用戶身份信息 token
     * @return 返回封裝了用戶信息的 AuthenticationInfo 實例
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
            throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String username = String.valueOf(token.getUsername());
        // 從數據庫獲取對應用戶名的用戶
        User user = usermapper.findByUsername(username);
        if (user == null) {
            throw new AccountException("不存在此用戶");
        }
        // 獲取鹽值,即用戶名
        ByteSource salt = ByteSource.Util.bytes(username);
        //注意,數據庫中的user的密碼必須是要經過md5加密,不然還是會拋出異常!!!!!
        return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), salt, getName());
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章