Shiro 禁用session 自定义authc过滤器

做毕设的时候遇到的禁用session 各种报错 ,所以记录一下

很多篇同样的文章 都说这个一加上就报错,但是这个工厂是必须要加入的 在源码里面有说到 debug就看到了
StatelessDefaultSubjectFactory.java

public class StatelessDefaultSubjectFactory extends DefaultWebSubjectFactory {
    @Override
    public Subject createSubject(SubjectContext context) {
        //不创建session
        context.setSessionCreationEnabled(false);
        return super.createSubject(context);
    }
}

ShiroConfig.java

securityManager.setSubjectFactory(new StatelessDefaultSubjectFactory());

无状态shiro报DisabledSessionException

ShiroConfig.java中 有一个坑
authc 必须认证 / 默认拦截器authc,源码中有去调用getSession()方法的,但这个时候我们又不创建session,这时就报错。所以要自己去定义一个Filter();


在创建初 如果用自己写的realm的话 比较的流程是 通过加密两个不同的realm 得到一个hash值,密码比较器 doCredentialsMatch… 就会去取这两个Realm 的 SimpleAuthenticationInfo() (该方法加密后得到的是Hash) 根据两个hash 进行equals比较

AuthenticatingRealm.java 主要调用

 protected void assertCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) throws AuthenticationException {
        CredentialsMatcher cm = this.getCredentialsMatcher();
        if (cm != null) {
            if (!cm.doCredentialsMatch(token, info)) {
                String msg = "Submitted credentials for token [" + token + "] did not match the expected credentials.";
                throw new IncorrectCredentialsException(msg);
            }
        } else {
            throw new AuthenticationException("A CredentialsMatcher must be configured in order to verify credentials during authentication.  If you do not wish for credentials to be examined, you can configure an " + AllowAllCredentialsMatcher.class.getName() + " instance.");
        }
    }

其中

!cm.doCredentialsMatch(token, info)

会去调用 JwtCredentialsMatcher,一定要注意 在JwtCredentialsMatcher是否返回true


最主要的密码认证器
HashedCredentialsMatcher.java

 public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        Object tokenHashedCredentials = this.hashProvidedCredentials(token, info);
        Object accountCredentials = this.getCredentials(info);
        return this.equals(tokenHashedCredentials, accountCredentials);
    }

tokenHashedCredentials 来源于你输入的账号(JwtToken.getCredentials())
accountCredentials 来源于你

还有一个细节点在于

public class JwtToken implements AuthenticationToken {
...
@Override
    public Object getCredentials() {
    		// 注意 重写这个方法中 需要return 的是密码!!!!
    		// 很多博客中都是返回token  或者返回一个user对象,但实则不是
    		return JWTUtils.verify(token).getClaim("userPassword").asString().toCharArray();
    }
...
}

至于 为什么密码要toCharArray (网上给出的回答)
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值