Shiro自定义过滤器
项目中需要所有首次登录的用户必须修改密码才可使用系统,项目采用的是Shiro框架。
突然想到了配置文件org.apache.shiro.spring.web.ShiroFilterFactoryBean中的loginUrl,校验未登录则跳转到登录地址。索性研究了它的源码后可以继承AccessControlFilter自定义自己的过滤器。
自定义Shiro过滤器:
package com.lwj.modules.filter; import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse; import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.StringUtils;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.util.WebUtils; import com.lwj.modules.shiro.realm.Principal; /**
* 首次登陆必须修改密码
*
* @ClassName: ChangePasswordFilter
* @author lwj
* @version 1.0.0
*/
public class ChangePasswordFilter extends AccessControlFilter { /**
* 登录地址
*/
static final String LOGIN_URL = "/login.html";
/**
* 修改密码地址
*/
static final String NEW_PASSWORD_URL = "/login/new_password.html"; @Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
throws Exception {
// TODO Auto-generated method stub
return false;
} @Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { Subject subject = getSubject(request, response);
if (subject.getPrincipal() == null) {// 表示没有登录,重定向到登录页面
saveRequest(request);
WebUtils.issueRedirect(request, response, LOGIN_URL);
} else {
Principal principal = (com.lwj.modules.shiro.realm.Principal) subject.getPrincipal();
if (principal.getChangedPassword() == null || !principal.getChangedPassword()) {
if (StringUtils.hasText(NEW_PASSWORD_URL)) {// 如果首次登录未修改密码,则跳转到修改密码页面
WebUtils.issueRedirect(request, response, NEW_PASSWORD_URL);
} else {
WebUtils.toHttp(response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
}
}
return true;
} }
补充Principal类,这个类在登录的时候用于用户的认证,相当于保存当前登录用户的基本信息。
package com.lwj.modules.shiro.realm; import java.io.Serializable; /**
*
* @Description :身份信息
* @author : lwj
* @version : 1.0.0
* @Date :2016-11-13 11:21:56
*/
public class Principal implements Serializable { /** 用户Cookie名称 */
public static final String USER_COOKIE_NAME = "u_c_n"; /** "身份信息"参数名称 */
public static final String PRINCIPAL_ATTRIBUTE_NAME = Principal.class.getName() + ".PRINCIPAL";
/**
*
*/
private static final long serialVersionUID = 1L; /** ID */
private Integer id; /** 用户名 */
private String username;/**
* 角色ID
*/
private Integer roleId;
/**
* 登录IP
*/
private String ip;/**
* 第一次登陆是否修改密码(平台)
*/
private Boolean changedPassword; /**
* @param id
* ID
* @param username
* 用户名
*/
public Principal(Integer id, String username,Boolean changedPassword, Integer roleId, String ip) {
this.id = id;
this.username = username;
this.changedPassword = changedPassword;
this.roleId = roleId;
this.ip = ip;
} /**
* 获取ID
*
* @return ID
*/
public Integer getId() {
return id;
} /**
* 设置ID
*
* @param id
* ID
*/
public void setId(Integer id) {
this.id = id;
} /**
* 获取用户名
*
* @return 用户名
*/
public String getUsername() {
return username;
} /**
* 设置用户名
*
* @param username
* 用户名
*/
public void setUsername(String username) {
this.username = username;
} public Integer getRoleId() {
return roleId;
} public void setRoleId(Integer roleId) {
this.roleId = roleId;
}
public String getIp() {
return ip;
} public void setIp(String ip) {
this.ip = ip;
} public Boolean getChangedPassword() {
return changedPassword;
} public void setChangedPassword(Boolean changedPassword) {
this.changedPassword = changedPassword;
} }
配置shiro.xml
<!-- 自定义shiro的filter -->
<bean id="changedPassword" class="com.lwj.modules.filter.ChangePasswordFilter" /> <!-- shiroFilter -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- Shiro的核心安全接口,这个属性是必须的 -->
<property name="securityManager" ref="securityManager" />
<!-- 要求登录时的链接 -->
<property name="loginUrl" value="/login.html" />
<!-- 登录成功后要跳转的链接 -->
<property name="successUrl" value="/" />
<!-- 用户访问未对其授权的资源时,所显示的链接 -->
<property name="unauthorizedUrl" value="/common/unauthorized.html" /> <property name="filterChainDefinitions">
<value><!-- 用户首次登录必须修改密码 -->
/index/* = changedPassword
/navigation/* = authc,changedPassword
/** = authc
</value>
</property>
<property name="filters">
<map>
<entry key="changedPassword" value-ref="changedPassword" />
</map>
</property>
</bean>
Shiro自定义过滤器的更多相关文章
- shiro 自定义过滤器,拦截过期session的请求,并且以ajax形式返回
自定义过滤器: public class CustomFormAuthenticationFilter extends FormAuthenticationFilter { @Override pro ...
- shiro使用框架,自定义过滤器
1.shiro配置文件配置 <!-- Shiro Filter --> <bean id="shiroFilter" class="org.apache ...
- Shiro自定义Realm时用注解的方式注入父类的credentialsMatcher
用Shiro做登录权限控制时,密码加密是自定义的. 数据库的密码通过散列获取,如下,算法为:md5,盐为一个随机数字,散列迭代次数为3次,最终将salt与散列后的密码保存到数据库内,第二次登录时将登录 ...
- shiro的过滤器
shiro的过滤器也是不多的我们可以自定义的方法,它的继承体系如下: 另外UserFilter是继承于AccessControlFilter 1.NameableFilter NameableFilt ...
- shiro自定义拦截url
在实际项目上,我们针对不同的用户(guste,user,admin,mobile user)等等,需要进入不同的页面,比如,手机端用户需要进入Mobile/这个路径下的,这个时候,我们需要自定义拦截u ...
- Shiro 自定义登陆、授权、拦截器
Shiro 登陆.授权.拦截 按钮权限控制 一.目标 Maven+Spring+shiro 自定义登陆.授权 自定义拦截器 加载数据库资源构建拦截链 使用总结: 1.需要设计的数据库:用户.角色.权限 ...
- 解决shiro自定义filter后,ajax登录无法登录,并且无法显示静态资源的问题
这个问题困扰了我一天,看了下面两个文章,豁然开朗: https://www.cnblogs.com/gj1990/p/8057348.html https://412887952-qq-com.ite ...
- 实现MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器
MVC开发中几种以AOP方式实现的Filters是非常好用的,默认情况下,我们通过App_Start中的FilterConfig来实现的过滤器注册是全局的,也就是整个应用程序都会使用的,针对单独的Fi ...
- lucene自定义过滤器
先介绍下查询与过滤的区别和联系,其实查询(各种Query)和过滤(各种Filter)之间非常相似,可以这样说只要用Query能完成的事,用过滤也都可以完成,它们之间可以相互转换,最大的区别就是使用过滤 ...
随机推荐
- Linux定时任务调度
⒈概述 任务调度:是指系统在某个时间执行的特定的命令或程序 分类:1)系统任务:有些重要的工作必须周而复始的执行,例如病毒扫描等 2)用户任务:个别用户可能希望定时执行某些程序,例如mysql定时备份 ...
- win10-Anaconda2-Theano-cuda7.5-VS2013
两天的辗转反侧,终于灵光一现找到了错误. 首先,我在win10下配置好了gpu和cudnn版本的caffe.但是因为win平台的限制,caffe用的不够舒服.因为之前用过一阵子theano,虽然很慢, ...
- cocos2d-x在App中的应用
cocos2d-x是一个应用广泛的开源游戏引擎,主要是应用与开发2D游戏,开源运行于多个平台,如果只是针对于移动端平台而言,可以运行于android和ios平台. cocos2d-x目前的版本是3.1 ...
- 关于Java源文件中public类的问题
结论: 一个Java源文件中最多只能有一个public类,当有一个public类时,源文件名必须与之一致,否则无法编译: 如果源文件中没有一个public类,则文件名与类中没有一致性要求: 至于mai ...
- Expm 1_3 数组中逆序对个数问题
有一个数的序列A[1].A[2] .A[3] .…… .A[n],若i<j,并且A[i]>A[j],则称A[i]与A[j]构成了一个逆序对,设计算法求数列A中逆序对的个数. package ...
- VM 安装 linux Enterprise_R5_U4_Server_I386_DVD教程图解
ocp 学习笔记 20161126--------linux 笔记整理 一:安装linux系统环境: 1:linux 系统安装包下载路径:链接:链接: https://pan.baidu.com/s/ ...
- Java多线程中wait语句的具体使用技巧
Java多线程在使用的时候会有很多语句需要我们具体的学习,在这其中wait()就是其中的一个.当然我们需要不断的努力学习才能掌握这一个语句的应用,下面的代码会对你学习Java多线程有所帮助. clas ...
- python for dl
算是python的简明教程吧,总结的不错: https://zhuanlan.zhihu.com/p/24162430 python for opencv: https://zhuanlan.zhih ...
- hdu4122
题目很长,有点恶心,但实际上是个单调队列 没搞出来,题解 https://blog.csdn.net/lvshubao1314/article/details/46910271 #include< ...
- poj3237树链剖分边权+区间取负
树链剖分+线段树lazy-tag在树链上操作时千万不要写错.. /* 树链剖分+线段树区间变负 */ #include<iostream> #include<cstring> ...