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来控制。

登录时验证:

 1 /**
 2  *
 3  */
 4 package com.autrade.xxx.shiro;
 5
 6 import javax.servlet.ServletRequest;
 7 import javax.servlet.ServletResponse;
 8
 9 import org.apache.commons.lang.StringUtils;
10 import org.apache.shiro.authc.AuthenticationException;
11 import org.apache.shiro.authc.AuthenticationToken;
12 import org.apache.shiro.authc.IncorrectCredentialsException;
13 import org.apache.shiro.authc.UnknownAccountException;
14 import org.apache.shiro.subject.Subject;
15 import org.apache.shiro.web.util.WebUtils;
16 import org.springframework.stereotype.Service;
17
18 import com.autrade.sptmasterweb.util.FailCacheUtils;
19
20 /**
21  * 表单验证(包含验证码)过滤类
22
23  *
24  */
25 @Service
26 public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.FormAuthenticationFilter {
27
28     public static final String DEFAULT_MESSAGE_PARAM = "message";
29
30
31     @Override
32     protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
33         AuthenticationToken token = createToken(request, response);
34         if (token == null) {
35             String msg = "createToken method implementation returned null. A valid non-null AuthenticationToken " +
36                     "must be created in order to execute a login attempt.";
37             throw new IllegalStateException(msg);
38         }
39         try {
40             Long lockTime = FailCacheUtils.isLocked(token.getPrincipal().toString());
41             if (lockTime>0){
42                 request.setAttribute(DEFAULT_MESSAGE_PARAM, "错误次数过多,请稍后再试!");
43                 return true;
44             }
45             Subject subject = getSubject(request, response); //代表当前前台传过来的用户
46             subject.login(token);
47             return onLoginSuccess(token, subject, request, response);
48         } catch (AuthenticationException e) {
49             return onLoginFailure(token, e, request, response);
50         }
51     }
52     /**
53      * 登录失败调用事件
54      */
55     @Override
56     protected boolean onLoginFailure(AuthenticationToken token,
57             AuthenticationException e, ServletRequest request, ServletResponse response) {
58         String className = e.getClass().getName(), message = "";
59         if (IncorrectCredentialsException.class.getName().equals(className)
60                 || UnknownAccountException.class.getName().equals(className)){
61             message = "用户或密码错误, 请重试.";
62         }
63         else if (e.getMessage() != null && StringUtils.indexOf(e.getMessage(), "msg:")!=-1){
64             message = StringUtils.replace(e.getMessage(), "msg:", "");
65         }
66         else{
67             message = "系统出现点问题,请稍后再试!";
68             e.printStackTrace(); // 输出到控制台
69         }
70         request.setAttribute(getFailureKeyAttribute(), className);
71         request.setAttribute(DEFAULT_MESSAGE_PARAM, message);
72         String username = WebUtils.getCleanParam(request, FormAuthenticationFilter.DEFAULT_USERNAME_PARAM);
73         FailCacheUtils.addFailCnt(username);
74         return true;
75     }
76
77     @Override
78     protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request,
79             ServletResponse response) throws Exception {
80         String username = WebUtils.getCleanParam(request, FormAuthenticationFilter.DEFAULT_USERNAME_PARAM);
81         FailCacheUtils.remave(username);
82         return super.onLoginSuccess(token, subject, request, response);
83     }
84
85 }

自定义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()方法完成验证对比。

时间: 06-12

shiro+spring的相关文章

Caused by: java.lang.ClassNotFoundException: org.apache.shiro.spring.LifecycleBeanPostProcessor

1.错误描述 Caused by: java.lang.ClassNotFoundException: org.apache.shiro.spring.LifecycleBeanPostProcessor at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50) at org.codehaus.plexus.classworlds.realm.ClassRe

shiro+spring相关配置

一.在web.xml配制shiroFilter <!-- 配置Shiro过滤器,先让Shiro过滤系统接收到的请求 --> <!-- 这里filter-name必须对应applicationContext.xml中定义的<bean id="shiroFilter"/> --> <!-- 使用[/*]匹配所有请求,保证所有的可控请求都经过Shiro的过滤 --> <!-- 通常会将此filter-mapping放置到最前面(即其他fi

Shiro —— Spring 环境下的使用

一.使用 1.搭建基础环境 (1)导入 Spring 和 Shiro 的 Jar 包 正常导入 spring jar包 导入日志包 log4j-1.2.15.jar slf4j-api-1.6.1.jar slf4j-log4j12-1.6.1.jar 导入 shiro 包 shiro-core-1.2.2.jar shiro-ehcache-1.2.2.jar shiro-spring-1.2.2.jar shiro-web-1.2.2.jar (2)配置文件 web.xml 读取所有配置文件

shiro +spring + spring mvc+ mybatis整合【转】

CREATE TABLE `sys_permission` ( `id` bigint(20) NOT NULL COMMENT '主键', `name` varchar(128) NOT NULL COMMENT '资源名称', `type` varchar(32) NOT NULL COMMENT '资源类型:menu,button,', `url` varchar(128) DEFAULT NULL COMMENT '访问url地址', `percode` varchar(128) DEF

shiro+spring boot+mybatis启动循环引用问题解决思路和方案

启动报错:Error creating bean with name 'dataSource': Requested bean is currently in creation: Is there an unresolvable circular reference? 翻译过来的意思就是:创建bean"dataSource"报错:需要的bean正在被创建:是否有一个没解决的循环依赖? 更通俗点的解释就是:因为循环依赖的问题导致"dataSource"这个bean无法

web工程使用spring mvc+shiro进行权限控制

第1步:引入shiro相关jar包 ehcache-core-2.5.0.jar shiro-ehcache-1.2.3.jar shiro-core-1.2.3.jar shiro-web-1.2.3.jar shiro-spring-1.2.3.jar 第二步:web.xml配置 <!-- shiro的filter --> <!-- shiro过虑器,DelegatingFilterProxy通过代理模式将spring容器中的bean和filter关联起来 --> <fi

基于Spring + Spring MVC + Mybatis + shiro 高性能web构建

一直想写这篇文章,前段时间 痴迷于JavaScript.NodeJs.AngularJS,做了大量的研究,对前后端交互有了更深层次的认识. 今天抽个时间写这篇文章,我有预感,这将是一篇很详细的文章,详细的配置,详细的注释,看起来应该很容易懂. 用最合适的技术去实现,并不断追求最佳实践.这就是架构之道. 希望这篇文章能给你们带来一些帮助,同时希望你们可以为这个项目贡献你的想法. 源码地址:https://github.com/starzou/quick4j 点击打开 看我们的项目结构: 是一个典型

shiro的权限控制应用,集成spring项目,密码错误次数过多短时间锁定

以前对shiro都是一知半解,最近系统学了一遍shiro并集成到了在做的项目中. 下面就详细向大家描述一下shiro的用法. 首先是对spring的配置文件,如下: 1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3

maven项目中Spring整合Shiro配置文件(示例)

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schem