实现多Realm时,可能会出现的问题
问题背景
在实现多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时,可能会出现的问题的更多相关文章
- hibernate有关联关系删除子表时可能会报错,可以用个clear避免错误
//清除子表数据 public SalesSet removeSalesSetDistributor(SalesSet salesSet ){ List<SalesSetDistributor& ...
- Shiro自定义Realm时用注解的方式注入父类的credentialsMatcher
用Shiro做登录权限控制时,密码加密是自定义的. 数据库的密码通过散列获取,如下,算法为:md5,盐为一个随机数字,散列迭代次数为3次,最终将salt与散列后的密码保存到数据库内,第二次登录时将登录 ...
- MySQL查询语句练习题(面试时可能会遇到哦!)
Sutdent表的定义 字段名 字段描述 数据类型 主键 外键 非空 唯一 自增 Id 学号 INT(10) 是 否 是 是 是 Name 姓名 VARCHAR(20) 否 否 是 否 否 Sex 性 ...
- 安装ubuntu server时可能会需要的配置
1.修改源 笔者比较习惯用163的源,配置如下: sudo vi /etc/apt/sources.list 163源为: deb http://mirrors.163.com/ubuntu/ pre ...
- 用AJAX传值参数是中文时可能会乱码
1.ajax代码 function SelectSemesterBySchYear() { // alert('sssssss'); var temp1 = document.getElementBy ...
- 使用Spring配置shiro时,自定义Realm中属性无法使用注解注入解决办法
先来看问题 纠结了几个小时终于找到了问题所在,因为shiro的realm属于Filter,简单说就是初始化realm时,spring还未加载相关业务Bean,那么解决办法就是将springmvc ...
- 手把手教你从Core Data迁移到Realm
来源:一缕殇流化隐半边冰霜 (@halfrost ) 链接:http://www.jianshu.com/p/d79b2b1bfa72 前言 看了这篇文章的标题,也许有些人还不知道Realm是什么,那 ...
- 手把手教你从 Core Data 迁移到 Realm
前言 看了这篇文章的标题,也许有些人还不知道Realm是什么,那么我先简单介绍一下这个新生的数据库.号称是用来替代SQLite 和 Core Data的.Realm有以下优点: 使用方便 Realm并 ...
- Shiro探索1. Realm
1. Realm 是什么?汉语意思:领域,范围:王国:这个比较抽象: 简单一点就是:Realm 用来对用户进行认证和角色授权的 再简单一点,一个用户怎么判断它有没有登陆?这个用户是什么角色有哪些权限? ...
随机推荐
- 趣图:这是拿offer极高的面试经验
扩展阅读 趣图:面试谈薪资就要这种底气 趣图:IT培训出来找工作 趣图:这是招聘超神级别的程序员?
- P4395 [BOI2003]Gem 气垫车
树形dp 首先,我们可以考虑dp,把这个问题看成一个树的染色问题,用dp[i][j]表示以i为根节点,将树染成第i种颜色的最小代价,那么我们可以得到j的最大值是(log(maxn)/log(2)+1) ...
- 后端开发实践:Spring Boot项目模板
在我的工作中,我从零开始搭建了不少软件项目,其中包含了基础代码框架和持续集成基础设施等,这些内容在敏捷开发中通常被称为"第0个迭代"要做的事情.但是,当项目运行了一段时间之后再来反 ...
- LRU Cache & Bloom Filter
Cache 缓存 1. 记忆 2. 空间有限 3. 钱包 - 储物柜 4. 类似背代码模板,O(n) 变 O(1) LRU Cache 缓存替换算法 1. Least Recently Use ...
- 00 你的第一个C语言程序
C语言简介 C 语言是一种通用的.面向过程式的计算机程序设计语言,即编程语言. 为移植和开发 UNIX 操作系统,丹尼斯·里奇于1972年在贝尔电话实验室设计开发了 C 语言的第一个版本. C 语言同 ...
- 【题解】CF1426E Rock, Paper, Scissors
题目戳我 \(\text{Solution:}\) 考虑第二问,赢的局数最小,即输和平的局数最多. 考虑网络流,\(1,2,3\)表示\(Alice\)选择的三种可能性,\(4,5,6\)同理. 它们 ...
- WebStrom配置TypeScript开发环境
安装NodeJS node.js下载地址:https://nodejs.org/en/download/ 安装TypeScript npm install typescripot -g 新建tscon ...
- CSG:清华大学提出通过分化类特定卷积核来训练可解释的卷积网络 | ECCV 2020 Oral
论文提出类特定控制门CSG来引导网络学习类特定的卷积核,并且加入正则化方法来稀疏化CSG矩阵,进一步保证类特定.从实验结果来看,CSG的稀疏性能够引导卷积核与类别的强关联,在卷积核层面产生高度类相关的 ...
- for循环迭代可迭代对象
模仿for循环迭代可迭代对象,# for i in Iterable:# iterable >>> 迭代器.iterator# 可迭代对象 iterable# 迭代器.iterato ...
- 达梦产品技术支持培训-day7-DM8数据库备份与还原-原理
(本文部分内容摘自DM产品技术支持培训文档,如需要更详细的文档,请查询官方操作手册,谢谢) 1.DM8备份还原简介 1.1.基本概念 (1)表空间与数据文件 ▷ DM8表空间类型: ▷ SYSTEM ...