项目中需要所有首次登录的用户必须修改密码才可使用系统,项目采用的是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自定义过滤器的更多相关文章

  1. shiro 自定义过滤器,拦截过期session的请求,并且以ajax形式返回

    自定义过滤器: public class CustomFormAuthenticationFilter extends FormAuthenticationFilter { @Override pro ...

  2. shiro使用框架,自定义过滤器

    1.shiro配置文件配置 <!-- Shiro Filter --> <bean id="shiroFilter" class="org.apache ...

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

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

  4. shiro的过滤器

    shiro的过滤器也是不多的我们可以自定义的方法,它的继承体系如下: 另外UserFilter是继承于AccessControlFilter 1.NameableFilter NameableFilt ...

  5. shiro自定义拦截url

    在实际项目上,我们针对不同的用户(guste,user,admin,mobile user)等等,需要进入不同的页面,比如,手机端用户需要进入Mobile/这个路径下的,这个时候,我们需要自定义拦截u ...

  6. Shiro 自定义登陆、授权、拦截器

    Shiro 登陆.授权.拦截 按钮权限控制 一.目标 Maven+Spring+shiro 自定义登陆.授权 自定义拦截器 加载数据库资源构建拦截链 使用总结: 1.需要设计的数据库:用户.角色.权限 ...

  7. 解决shiro自定义filter后,ajax登录无法登录,并且无法显示静态资源的问题

    这个问题困扰了我一天,看了下面两个文章,豁然开朗: https://www.cnblogs.com/gj1990/p/8057348.html https://412887952-qq-com.ite ...

  8. 实现MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器

    MVC开发中几种以AOP方式实现的Filters是非常好用的,默认情况下,我们通过App_Start中的FilterConfig来实现的过滤器注册是全局的,也就是整个应用程序都会使用的,针对单独的Fi ...

  9. lucene自定义过滤器

    先介绍下查询与过滤的区别和联系,其实查询(各种Query)和过滤(各种Filter)之间非常相似,可以这样说只要用Query能完成的事,用过滤也都可以完成,它们之间可以相互转换,最大的区别就是使用过滤 ...

随机推荐

  1. Java对象与JSON互相转换jsonlib以及手动创建JSON对象与数组——(二)

    首先声明一下,jsonlib转换与GSON相比太差劲了,操作不是一般的繁琐.GSON可以直接转换成各种集合与对象类型.强烈推荐使用GSON.而且GSON一个方法就可以解决,jsonlib转来转去太繁琐 ...

  2. oracle修改日期格式

    查看默认的日期格式 select * from v$nls_parameters; 更改 alter session | system (范围) set xxxx=“yyyy-mm-dd” ;

  3. 腾讯云外网IP直通后,遇到网络问题

    通过内网机器,先重启网卡 service network restart cd /usr/local/etc ./modify_route.sh

  4. 出现“error LNK1169: 找到一个或多个多重定义的符号”的原因

    或许,有人真的会这样写程序吧...所以才会碰到如下哥们提出的问题. https://zhidao.baidu.com/question/131426210.html 出现这种问题的原因链接中的最佳答案 ...

  5. centos系统中perl进程病毒占用大量网络流量导致网络瘫痪的问题分析及解决方案

    故障现象: 1.系统在早上9点的时候非常慢,单台服务器占用流量很大,使交换机流量被占满,而连累挂在同一交换机上的其他应用也无法提供服务,或者速度非常慢     2.通过查看进程发现大量的perl程序占 ...

  6. jquery里面的$.each()方法

    $.each可以迭代jquery对象和数组 $(selector).each()专注于jquery对象的遍历

  7. Centos7 通过yum命令安装jdk1.8

    直接安装,不看原因 yum install java-1.8.0-openjdk* -y 1 分割线上下之选一个看即可. —————————————华丽的分割线—————————————— 先查看系统 ...

  8. OCM_第十四天课程:Section6 —》数据库性能调优_各类索引 /调优工具使用/SQL 优化建议

    注:本文为原著(其内容来自 腾科教育培训课堂).阅读本文注意事项如下: 1:所有文章的转载请标注本文出处. 2:本文非本人不得用于商业用途.违者将承当相应法律责任. 3:该系列文章目录列表: 一:&l ...

  9. jquery----ajax解决scrf问题

    前端ajax请求 $.ajax({ type:"PUT", //请求方式为put dataType:"JSON", url:'/updata/user/', d ...

  10. cf220B莫队

    用莫队比直接做快了很多.. #include<iostream> #include<cstring> #include<cstdio> #include<cm ...