问题背景 
在实现多Realm时,扩展了ModularRealmAuthenticator 和 UsernamePasswordToken,于是在MyAuthenticationToken token = (MyAuthenticationToken) authenticationToken时出现了转型异常。

扩展ModularRealmAuthenticator 的代码如下:

public class MyModularRealmAuthenticator extends ModularRealmAuthenticator {

    @Override
public AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {
MyAuthenticationToken token = (MyAuthenticationToken) authenticationToken;
String loginType = token.getLoginType();
Collection<Realm> realms = getRealms();
Collection<Realm> authRealms = new ArrayList<>();
for(Realm realm : realms){
if(realm.getName().equals(loginType)){
authRealms.add(realm);
}
} if(authRealms.size() == 1){
return doSingleRealmAuthentication(authRealms.iterator().next(), token);
} else {
return doMultiRealmAuthentication(authRealms, token);
}
} }

扩展UsernamePasswordToken的代码如下:

public class MyAuthenticationToken extends UsernamePasswordToken {

    private String loginType;

    public MyAuthenticationToken(final String username, final String password, String loginType){
super(username, password);
this.loginType = loginType;
} public String getLoginType() {
return loginType;
} public void setLoginType(String loginType) {
this.loginType = loginType;
}
}

从上面的扩展中我们看到,没有地方使用我们的自己扩展的MyAuthenticationToken类,只是转型而已,并没有去实例化它,这才是引起问题的根源,问题发现了要如何解决它呢?我们在配置的使用并并未制定表单过滤器,此时默认使用的是FormAuthenticationFilter,而Token默认使用的也是UsernamePasswordToken,由此看来,我们扩展的MyAuthenticationToken就成了摆设,此时就要想办法如何将我们的扩展引用到程序里去呢? 
既然默认的是UsernamePasswordToken,那么是如何将UsernamePasswordToken注入的呢?我们进入默认的Filter(FormAuthenticationFilter)可以看到createToken,这个是创建Token的,那么似乎可以和我们的Token搭上边了,FormAuthenticationFilter中的createToken如下:

protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
String username = this.getUsername(request);
String password = this.getPassword(request);
return this.createToken(username, password, request, response);
}

我们发现期间又调用了createToken,此createToken为父类的方法,我们可以看到FormAuthenticationFilter的声明为 public class FormAuthenticationFilter extends AuthenticatingFilter ,也即内部调用的token为AuthenticatingFilter的实现,继续看AuthenticatingFilter中的createToken实现,而createToken中又调用了自身createToken的重载,源码如下:

protected AuthenticationToken createToken(String username, String password, ServletRequest request, ServletResponse response) {
boolean rememberMe = this.isRememberMe(request);
String host = this.getHost(request);
return this.createToken(username, password, rememberMe, host);
} protected AuthenticationToken createToken(String username, String password, boolean rememberMe, String host) {
return new UsernamePasswordToken(username, password, rememberMe, host);
}

可以看到在重载的createToken中,UsernamePasswordToken终于现身了,那么此时,我们可以通过扩展FormAuthenticationFilter并重新createToken将我们扩展的Token引入即可,以下为扩展的FormAuthenticationFilter:

public class MyFormAuthenticationFilter extends FormAuthenticationFilter {

    @Override
protected MyAuthenticationToken createToken(ServletRequest request, ServletResponse response) {
String username = getUsername(request);
String password = getPassword(request);
String loginType = request.getParameter("loginType");
if("sys".equals(loginType)){
return new MyAuthenticationToken(username, password, "sys");
} else {
return new MyAuthenticationToken(username, password, "wx");
}
} }

扩展完成后,需要配置默认的过滤器为我们的扩展,shiro的配置如下:

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="/login" />
<property name="successUrl" value="/index"/>
<property name="unauthorizedUrl" value="/403"/>
<property name="filterChainDefinitions">
<value>
/favicon.ico = anon
/logout = logout
/** = authc
</value>
</property>
<property name="filters">
<map>
<entry key="authc" value-ref="myFormAuthenticationFilter" />
</map>
</property>
</bean> <bean id="myFormAuthenticationFilter" class="com.yuxiao.springboot.springbootmybatis.config.shiro.filter.MyFormAuthenticationFilter"/>

实现多Realm时,可能会出现的问题的更多相关文章

  1. hibernate有关联关系删除子表时可能会报错,可以用个clear避免错误

    //清除子表数据 public SalesSet removeSalesSetDistributor(SalesSet salesSet ){ List<SalesSetDistributor& ...

  2. Shiro自定义Realm时用注解的方式注入父类的credentialsMatcher

    用Shiro做登录权限控制时,密码加密是自定义的. 数据库的密码通过散列获取,如下,算法为:md5,盐为一个随机数字,散列迭代次数为3次,最终将salt与散列后的密码保存到数据库内,第二次登录时将登录 ...

  3. MySQL查询语句练习题(面试时可能会遇到哦!)

    Sutdent表的定义 字段名 字段描述 数据类型 主键 外键 非空 唯一 自增 Id 学号 INT(10) 是 否 是 是 是 Name 姓名 VARCHAR(20) 否 否 是 否 否 Sex 性 ...

  4. 安装ubuntu server时可能会需要的配置

    1.修改源 笔者比较习惯用163的源,配置如下: sudo vi /etc/apt/sources.list 163源为: deb http://mirrors.163.com/ubuntu/ pre ...

  5. 用AJAX传值参数是中文时可能会乱码

    1.ajax代码 function SelectSemesterBySchYear() { // alert('sssssss'); var temp1 = document.getElementBy ...

  6. 使用Spring配置shiro时,自定义Realm中属性无法使用注解注入解决办法

    先来看问题    纠结了几个小时终于找到了问题所在,因为shiro的realm属于Filter,简单说就是初始化realm时,spring还未加载相关业务Bean,那么解决办法就是将springmvc ...

  7. 手把手教你从Core Data迁移到Realm

    来源:一缕殇流化隐半边冰霜 (@halfrost ) 链接:http://www.jianshu.com/p/d79b2b1bfa72 前言 看了这篇文章的标题,也许有些人还不知道Realm是什么,那 ...

  8. 手把手教你从 Core Data 迁移到 Realm

    前言 看了这篇文章的标题,也许有些人还不知道Realm是什么,那么我先简单介绍一下这个新生的数据库.号称是用来替代SQLite 和 Core Data的.Realm有以下优点: 使用方便 Realm并 ...

  9. Shiro探索1. Realm

    1. Realm 是什么?汉语意思:领域,范围:王国:这个比较抽象: 简单一点就是:Realm 用来对用户进行认证和角色授权的 再简单一点,一个用户怎么判断它有没有登陆?这个用户是什么角色有哪些权限? ...

随机推荐

  1. 深入研究Broker是如何持久化的

    前言 上篇文章王子和大家讨论了一下RocketMQ生产者发送消息的底层原理,今天我们接着这个话题,继续深入聊一聊RocketMQ的Broker是如何持久化的. Broker的持久化对于整个Rocket ...

  2. java中的几种基础排序

    import java.util.Random;import java.util.Arrays; public class Puppy {     public static void main(St ...

  3. 吴恩达Machine Learning学习笔记(三)--逻辑回归+正则化

    分类任务 原始方法:通过将线性回归的输出映射到0-1,设定阈值来实现分类任务 改进方法:原始方法的效果在实际应用中表现不好,因为分类任务通常不是线性函数,因此提出了逻辑回归 逻辑回归 假设表示--引入 ...

  4. React手稿之State Hooks of Hooks

    React Hooks React在16.7.0-alpha.0版本中提到了Hooks的概念,目前还是Proposal阶段. 官方也陈述,接下来的90%的工作会投入到React Hooks中. 从目前 ...

  5. Spring AOP系列(二) — 动态代理引言

    接上一篇Spring AOP系列(一)- 代理模式,本篇来聊聊动态代理. 动态代理与静态代理的区别 要想了解动态代理与静态代理的区别,需要有两个前置知识点:java程序是如何执行的以及类加载机制. j ...

  6. pytorch和tensorflow的爱恨情仇之基本数据类型

    自己一直以来都是使用的pytorch,最近打算好好的看下tensorflow,新开一个系列:pytorch和tensorflow的爱恨情仇(相爱相杀...) 无论学习什么框架或者是什么编程语言,最基础 ...

  7. 18-SE-你说的都队

    文章目录 前言 建设银行app分析 招商银行app分析 中国银行app分析 工商银行app分析 总结 团队成员分工与评分 前言 18-SE-你说的都队所选项目题目为"村镇银行储蓄业务系统开发 ...

  8. matlab中figure 创建图窗窗口

    来源:https://ww2.mathworks.cn/help/matlab/ref/figure.html?searchHighlight=figure&s_tid=doc_srchtit ...

  9. CSG:清华大学提出通过分化类特定卷积核来训练可解释的卷积网络 | ECCV 2020 Oral

    论文提出类特定控制门CSG来引导网络学习类特定的卷积核,并且加入正则化方法来稀疏化CSG矩阵,进一步保证类特定.从实验结果来看,CSG的稀疏性能够引导卷积核与类别的强关联,在卷积核层面产生高度类相关的 ...

  10. 【LGR-070】洛谷 3 月月赛-官方题解

    本次免费为大家提供[LGR-070]洛谷 3 月月赛的官方题解,点个赞再走呗! 代码就不上了,大家可以到别的博客上去找找!希望这篇博客能对你有所帮助!