shiro+spring
公司自用的管理系统使用了shiro,但是对于这个登录页面跳转、登录的过程逻辑以及登录成功或者失败的跳转页面一直不理解,查看相关文档资料,整理出一些结果并本地调试测试,记录下备以后回顾之用。
对于spring+shiro,很多文档都是:搭建环境,然后配置web.xml,shiro spring配置文件,开发自己的realm、shiro的过滤器链以及spring controller等等内容。实际开发中,也是按照这套路来使用的。但是:对于localhost/xxx/login登录请求页面跳转,怎么感觉是直接请求spring而未通过shiro过滤器?
本地web.xml配置文件部分截图:
shiro配置:

spring mvc作为请求控制器,shiro作为权限过滤器,shiro对所有请求url进行判断,并指定相关的过滤器,例如/xxx/login指定的是authc过滤器(验证,这些页面必须验证后才能访问,也就是我们说的登录后才能访问),过滤器逻辑如果抛出异常表示认证失败,过滤器会转向shiroFilter配置的loginUrl地址,认证成功会转向配置的successUrl地址。而转向过后的逻辑将是由springmvc来控制。
登录时验证:
/**
*
*/
package com.autrade.xxx.shiro; import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.stereotype.Service; import com.autrade.sptmasterweb.util.FailCacheUtils; /**
* 表单验证(包含验证码)过滤类 *
*/
@Service
public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.FormAuthenticationFilter { public static final String DEFAULT_MESSAGE_PARAM = "message"; @Override
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
AuthenticationToken token = createToken(request, response);
if (token == null) {
String msg = "createToken method implementation returned null. A valid non-null AuthenticationToken " +
"must be created in order to execute a login attempt.";
throw new IllegalStateException(msg);
}
try {
Long lockTime = FailCacheUtils.isLocked(token.getPrincipal().toString());
if (lockTime>0){
request.setAttribute(DEFAULT_MESSAGE_PARAM, "错误次数过多,请稍后再试!");
return true;
}
Subject subject = getSubject(request, response); //代表当前前台传过来的用户
subject.login(token);
return onLoginSuccess(token, subject, request, response);
} catch (AuthenticationException e) {
return onLoginFailure(token, e, request, response);
}
}
/**
* 登录失败调用事件
*/
@Override
protected boolean onLoginFailure(AuthenticationToken token,
AuthenticationException e, ServletRequest request, ServletResponse response) {
String className = e.getClass().getName(), message = "";
if (IncorrectCredentialsException.class.getName().equals(className)
|| UnknownAccountException.class.getName().equals(className)){
message = "用户或密码错误, 请重试.";
}
else if (e.getMessage() != null && StringUtils.indexOf(e.getMessage(), "msg:")!=-1){
message = StringUtils.replace(e.getMessage(), "msg:", "");
}
else{
message = "系统出现点问题,请稍后再试!";
e.printStackTrace(); // 输出到控制台
}
request.setAttribute(getFailureKeyAttribute(), className);
request.setAttribute(DEFAULT_MESSAGE_PARAM, message);
String username = WebUtils.getCleanParam(request, FormAuthenticationFilter.DEFAULT_USERNAME_PARAM);
FailCacheUtils.addFailCnt(username);
return true;
} @Override
protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request,
ServletResponse response) throws Exception {
String username = WebUtils.getCleanParam(request, FormAuthenticationFilter.DEFAULT_USERNAME_PARAM);
FailCacheUtils.remave(username);
return super.onLoginSuccess(token, subject, request, response);
} }
自定义realm中:
认证:
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
//token令牌,也就相当于一张表格,你要去验证,你就得填个表,里面写好用户名密码,交给公安局的同志给你验证
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
InternalUserDownEntity userAcctInfoEntity = internalUserService.findInternalUserInfoByUserName(token.getUsername());if (userAcctInfoEntity!=null)
{
//用户我们可以前面的令牌也就是我说的表格来取的,我们前台提交给公安同志一个表格,里面有用户密码,
//但需要注意的是,我们在这里并不把表格中的用户密码路数据库中的用户密码进行比较,我们只是根据表格中的用户名把密码查出来,
//然后把数据库的用户密码放在一个SimpleAuthenticationInfo对象中返回即可,这位公安同志不负责验证,只负责验证的材料
InternalUserAuthEntity userAuthEntity = new InternalUserAuthEntity();
userAuthEntity.setUserId(userAcctInfoEntity.getUserId());
ShiroUser shiroUser = new ShiroUser(userAcctInfoEntity.getUserId(), token.getUsername(),token.getUsername(), userAuthEntity);
return new SimpleAuthenticationInfo(shiroUser,userAcctInfoEntity.getPassWord(), getName());
}
else
{
return null;
}
}
以上准备好比对数据,什么时候验证呢?
(1)executeLogin中调用subject.isAuthenticated()时
(2)由于之前的shiro spring配置文件中配置了/login = authc, 配了authc过滤器,shiro会自动调用subject.isAuthenticated()方法完成验证对比。
shiro+spring的更多相关文章
- Shiro —— Spring 环境下的使用
一.使用 1.搭建基础环境 (1)导入 Spring 和 Shiro 的 Jar 包 正常导入 spring jar包 导入日志包 log4j-1.2.15.jar slf4j-api-1.6.1.j ...
- shiro+spring相关配置
首先pom中添加所需jar包: <!-- shiro start --> <dependency> <groupId>org.apache.shiro</gr ...
- 【shiro】报错:Caused by: java.lang.ClassNotFoundException: org.apache.shiro.spring.LifecycleBeanPostProcessor
Caused by: java.lang.ClassNotFoundException: org.apache.shiro.spring.LifecycleBeanPostProcessor at o ...
- Shiro+Spring+SpringMVC+Mybatis整合
Demo源码地址,v1.0分支 https://github.com/jxjy/hr
- Spring Boot 添加Shiro支持
前言: Shiro是一个权限.会话管理的开源Java安全框架:Spring Boot集成Shiro后可以方便的使用Session: 工程概述: (工程结构图) 一.建立Spring Boot工程 参照 ...
- 基于Spring + Spring MVC + Mybatis + shiro 高性能web构建
一直想写这篇文章,前段时间 痴迷于JavaScript.NodeJs.AngularJS,做了大量的研究,对前后端交互有了更深层次的认识. 今天抽个时间写这篇文章,我有预感,这将是一篇很详细的文章,详 ...
- Spring MVC 急速集成 Shiro 实录
相信有很多的程序员,不愿意进行用户管理这块代码实现. 原因之一,不同的JavaEE 系统,用户管理都会有个性化的实现,逻辑很繁琐. 而且是系统门面,以后背锅的几率非常大,可谓是低收益高风险. 最近在系 ...
- spring 集成shiro 之 自定义过滤器
在web.xml中加入 <!-- 过期时间配置 --> <session-config><session-timeout>3</session-timeout ...
- 基于Spring框架的Shiro配置
一.在web.xml中添加shiro过滤器 <!-- Shiro filter--> <filter> <filter-name>shiroFilter</ ...
随机推荐
- day01计算机硬件基础
1.cpu\内存\硬盘 2.存储器 操作系统 是什么 为什么 如何用 1.什么是编程语言: 语言是一个事物与另一个事物沟通的表达方式 编程语言即程序员与计算机沟通的介质 计算机是程序员的奴隶 2.什么 ...
- Math和Date
Math和Date 一.对象 1.对象的概念 对象的本质:键值对,属性名和属性值 对象的意义:存储数据,编程 对象中的变量:属性 对象中的函数:方法 2.对象的赋值 var obj = {}; var ...
- 二阶段js 入门知识点 自我总结复习
二阶段自我总复习 1.javascript基础 : 客户端 安全性 跨平台 脚本语言 三大结构: 顺序 .选择.循环 顺序:运算符和表达式 ...
- [系列] go-gin-api 规划目录和参数验证(二)
目录 概述 规划目录结构 模型绑定和验证 自定义验证器 制定 API 返回结构 源码地址 go-gin-api 系列文章 概述 首先同步下项目概况: 上篇文章分享了,使用 go modules 初始化 ...
- 随笔编号-08 MYSQL 存储过程,5分钟执行调用过程;
delimiter //DROP PROCEDUREIF EXISTS jdt.day_instan_data_task// CREATE PROCEDURE jdt.day_instan_data_ ...
- NanoPi NEO2 学习笔记 1:安装系统、首次开机和一些设置
初识NEO2 前几天搞到了一块NanoPi NEO2,A53的核心,512M内存,一个千兆网口,非常小的体积,质量也不错,非常满意,140元的价格可以买到这样一块ARM开发板也是非常划算了,非常适合低 ...
- 【解决】TLS/SSLError问题导致无法使用pip或conda安装软件包
Copy these files from the ./Library/bin to ./DLLs/ :libcrypto-1_1-x64.*libssl-1_1-x64.* 解决 欢迎关注↓↓↓ 头 ...
- ImportError: cannot import name '_obtain_input_shape' from 'keras.applications.imagenet_utils'
报错 Using TensorFlow backend. Traceback (most recent call last): File "D:/PyCharm 5.0.3/WorkSpac ...
- BZOJ2152 聪聪可可 (点分治)
2152: 聪聪可可 题意: 在一棵边带权的树中,问任取两个点,这两个点间的权值和是3的倍数的概率. 思路: 经典的点分治题目. 利用点分治在计算所有路径长度,把路径长度对3取模,用t[0],t[1] ...
- CodeForces 590C Three States BFS
Three Statesy 题解: 以3个大陆为起点,都dfs一遍,求出该大陆到其他点的最小距离是多少, 然后枚举每个点作为3个大陆的路径交点. 代码: #include<bits/stdc++ ...