实现多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 用来对用户进行认证和角色授权的 再简单一点,一个用户怎么判断它有没有登陆?这个用户是什么角色有哪些权限? ...
随机推荐
- Sorted Adjacent Differences(CodeForces - 1339B)【思维+贪心】
B - Sorted Adjacent Differences(CodeForces - 1339B) 题目链接 算法 思维+贪心 时间复杂度O(nlogn) 1.这道题的题意主要就是让你对一个数组进 ...
- Redis5设计与源码分析读后感(二)简单动态字符串SDS
一.引言 学习之前先了解几个概念: SDS定义:简单动态字符串,Redis的基本数据结构之一,用于储存字符串和整型数据. 二进制安全:C语言中用"\0"表示字符串结束,如果字符串本 ...
- dubbo学习(十)spring boot整合dubbo
工程搭建与配置 生产者 1.创建一个生产者的spring boot工程,配置好依赖,并把接口实现类文件夹复制到新的工程里 2.pom.xml配置dubbo的相关依赖 <!-- Dubbo Spr ...
- 记一次springboot(2.1.6)+springcloud(Greenwich.SR2) 配置中心搭建,支持在线刷新
1.配置eureka注册中心 EureKaSpringApplication: package com.crow.eureka; import org.springframework.boot.Spr ...
- Zookeeper 笔记小结
转自: https://www.cnblogs.com/raphael5200/p/5285583.html 1.Zookeeper的角色 » 领导者(leader),负责进行投票的发起和决议,更新 ...
- 【SCOI2016】背单词
P3294[SCOI2016]背单词 [提示] 这道题大概是告诉我们,让我们用一堆n个单词安排顺序,如果当前位置为x,当前单词的后缀没在这堆单词出现过,代价就为x,这里的后缀是原意,但不算自己(不算本 ...
- Linux中的硬链接和软连接
1.Linux链接概念Linux链接分两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link).默认情况下,ln命令产生硬链接. [硬连接]硬连接指通过索引节点 ...
- Python 自动化测试全攻略:五种自动化测试模型实战详解
随着移动互联网的发展,软件研发模型逐步完善,软件交付质量越来越受到软件公司的重视,软件测试技术特别是自动化测试技术开始在软件系统研发过程中发挥着越来越重要的作用. 与传统的手工测试技术相比,自动化测试 ...
- PyCharm 上安装 Package(以 pandas 为例)
一.使用 PyCharm 软件安装 pandas 包 1.打开 PyCharm 2.点击右上角 "Files" →"Settings..." 3.弹出" ...
- shell-的特殊变量-位置变量$0 $n $* $# $@详解
一:shell特殊变量 1. 位置变量 $0 获取当前执行的shell脚本的文件名,包括路径 $n 获取当前执行的shell脚本的第n个参数值,n=1..9,当n为0时表示脚本的文件名,如果n大于9 ...