(转) shiro权限框架详解06-shiro与web项目整合(上)
http://blog.csdn.net/facekbook/article/details/54947730
shiro和web项目整合,实现类似真实项目的应用
本文中使用的项目架构是springMVC+mybatis,所以我们是基于搭建好的项目进行改造的。
- 将shiro整合到web应用中
- 登录
- 退出
- 认证信息在页面展现,也就是显示菜单
- shiro的过滤器
将shiro整合到web应用中
数据库脚步
sql脚步放到项目中,项目上传到共享的资源中,文章最后给出共享url。
去除项目中不使用shiro实现认证的拦截器
<!--拦截器 -->
<!-- <mvc:interceptors> <mvc:interceptor> -->
<!-- 用户认证拦截 -->
<!-- <mvc:mapping path="/**" /> <bean class="cn.itcast.ssm.controller.interceptor.LoginInterceptor"></bean>
</mvc:interceptor> <mvc:interceptor> -->
<!-- 授权拦截 -->
<!-- <mvc:mapping path="/**" /> <bean class="cn.itcast.ssm.controller.interceptor.PermissionInterceptor"></bean>
</mvc:interceptor> </mvc:interceptors> -->
添加shiro的jar包
除了前面文章提到的shiro-core相关的jar包,还需要如下:
- 与web整合的 shiro-web-1.2.3.jar
- 与spring整合的 shiro-spring-1.2.3.jar
- 与ehcache整合的 shiro-ehcache-1.2.3.jar
在web.xml中配置shiro的filter
在web系统中,shiro 也是通过filter进行拦截的。filter拦截后将操作交给filterChain(过滤器炼)。shiro中提供了多个filter,在栏目 shiro的过滤器 会全部介绍
在web中配置filter,如下:
<!--shirofilter-->
<!-- shiro过滤器,DelegatingFilterProxy通过代理模式将spring容器的bean和filter关联起来 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<!--设置true由servlet容器控制filter的生命周期-->
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
<!--设置spring容器filter的bean id,如果不设置则找与filter-name一致的bean -->
<init-param>
<param-name>targetBeanName</param-name>
<param-value>shiroFilter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
新建applicationContext-shiro.xml文件
内容下图:
<!-- web.xml中shiro的filter对应的bean -->
<!-- shiro的web过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<!-- logiUrl认证提交地址,如果没有认证通过将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 -->
<property name="loginUrl" value="/login.action" />
<!-- 认证成功后统一跳转到first.action,建议不配置,shiro认证成功自动到上一个链接 -->
<property name="successUrl" value="/first.action" />
<!-- 通过unauthorizedUrl指定没有权限时跳转页面 -->
<property name="unauthorizedUrl" value="/refuse.jsp" />
<!-- 过滤器链定义,从上向下顺序执行,一般将/**放在最后面 -->
<property name="filterChainDefinitions">
<value>
<!--静态资源可以匿名访问 -->
/images/** = anon
/js/** = anon
/styles/** = anon
<!--登录验证码匿名访问-->
/validatecode.jsp = anon
<!--任何链接都可以不认证访问-->
/** = anon
</value>
</property>
</bean>
<!--securityManager安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="customRealm" />
</bean>
<!-- 自定义的realm -->
<bean id="customRealm" class="cn.itcast.ssm.shiro.CustomRealm"/>
- 1
上面配置的CustomRealm 的内容和文章shiro权限框架详解05-shiro授权的CustomRealm一样。
测试是否整合成功
在界面输入CustomRealm 代码中的账号为 zhangsan 密码为 123 可以进入欢迎页面。 
但是并没有菜单和相关用户信息
登录功能
原理
由于登录使用的是 org.apache.shiro.web.filter.authc.FormAuthenticationFilter filter实现的,具体流程如下:
如果用户没有认证时,请求上面配置的loginUrl进行认证,用户的身份信息和密码提交到loginUrl,FormAuthenticationFilter拦截取出request中的username和password(参数的key是可以进行配置的,下一篇blog介绍)参数值。FormAuthenticationFilter调用realm传入一个token(包含username和password),realm根据username查询用户信息,如果查询不到,返回null,FormAuthenticationFilter向request域中填充一个参数,key为shiroLoginFailure 记录异常信息。如果不为空的话,返回AuthenticationInfo 类。
修改登录页面
由于FormAuthenticationFilter的身份信息和密码的请求参数的key默认是(username和password),修改login.jsp页面的账号和密码输入框name属性值,并注释掉验证码的代码。
修改controller类
修改LoginController 的 login 方法如下:
@RequestMapping("/login")
public String login(HttpServletRequest request)throws Exception{
//如果登录失败从request中获取认证异常信息,shiroLoginFailure就是shiro异常类的全限定名
String exceptionClassName = (String) request.getAttribute("shiroLoginFailure");
if(exceptionClassName!=null){
if(UnknownAccountException.class.getName().equals(exceptionClassName)){
throw new CustomException("账号不存在");
}else if(IncorrectCredentialsException.class.getName().equals(exceptionClassName)){
throw new CustomException("用户名或密码错误");
}else {
throw new Exception();//最终在异常处理器生成未知错误
}
}
//此方法不处理登录成功(认证成功),shiro认证成功会自动跳转到上一个请求路径。
//登录失败还到login页面
return "login";
}
这个方法只有校验不通过的时候才会执行。真正的校验方法是在自定义的realm中,校验身份是否正确。
修改认证拦截器
将所有请求都改为需要认证才能访问的。
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<!-- logiUrl认证提交地址,如果没有认证通过将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 -->
<property name="loginUrl" value="/login.action" />
<!-- 认证成功后统一跳转到first.action,建议不配置,shiro认证成功自动到上一个链接 -->
<property name="successUrl" value="/first.action" />
<!-- 通过unauthorizedUrl指定没有权限时跳转页面 -->
<property name="unauthorizedUrl" value="/refuse.jsp" />
<!-- 自定义filter配置 -->
<property name="filters">
<map>
<entry key="authc" value-ref="formAuthenticationFilter"/>
</map>
</property>
<!-- 过滤器链定义,从上向下顺序执行,一般将/**放在最后面 -->
<property name="filterChainDefinitions">
<value>
<!--静态资源可以匿名访问 -->
/images/** = anon
/js/** = anon
/styles/** = anon
/validatecode.jsp = anon
<!-- /**=authc 表示所有的url都需要认证才能访问 -->
/** = authc
</value>
</property>
</bean>
验证登录功能
在登录界面输入账号为 zhangsan 密码为 123 验证是否登录成功,然后输入错误的账号,控制台出现下面的异常信息:
如果输入密码错误:
异常信息和前面Java项目演示的一样。
退出
退出不需要我们自己实现,只要去访问一个退出的url(该url是可以不存在的)即可,由LogoutFilter filter处理,清除session。在applicationContext.xml配置logoutFilter
<!-- web.xml中shiro的filter对应的bean -->
<!-- shiro的web过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<!-- logiUrl认证提交地址,如果没有认证通过将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 -->
<property name="loginUrl" value="/login.action" />
<!-- 认证成功后统一跳转到first.action,建议不配置,shiro认证成功自动到上一个链接 -->
<property name="successUrl" value="/first.action" />
<!-- 通过unauthorizedUrl指定没有权限时跳转页面 -->
<property name="unauthorizedUrl" value="/refuse.jsp" />
<!-- 自定义filter配置 -->
<property name="filters">
<map>
<entry key="authc" value-ref="formAuthenticationFilter"/>
</map>
</property>
<!-- 过滤器链定义,从上向下顺序执行,一般将/**放在最后面 -->
<property name="filterChainDefinitions">
<value>
<!--静态资源可以匿名访问 -->
/images/** = anon
/js/** = anon
/styles/** = anon
/validatecode.jsp = anon
<!-- 请求logout.action地址,shiro去清除session -->
/logout.action = logout
<!-- /**=authc 表示所有的url都需要认证才能访问 -->
/** = authc
</value>
</property>
</bean>
删除原来的退出方法。
菜单显示
修改realm从数据库查询用户信息及用户拥有的菜单设置在AuthenticatorInfo中。具体代码如下:
/**
* 用于认证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
throws AuthenticationException {
//第一步:通过token获取身份信息
String userCode = (String) token.getPrincipal();
if (!"zhangsan".equals(userCode)) {// 这里模仿查询不到
return null;
}
String password = "123";
//模拟数据activeUser就是用户身份信息
ActiveUser activeUser = new ActiveUser();
activeUser.setUserid("zhangsan");
activeUser.setUsercode("zhangsan");
activeUser.setUsername("张三");
//查询菜单信息
List<SysPermission> menus = null;
try {
menus = sysService.findMenuListByUserId(activeUser .getUsercode());
} catch (Exception e) {
e.printStackTrace();
}
activeUser.setMenus(menus);
//如果查询到结果返回AuthenticationInfo
AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(activeUser, password, "");
return authenticationInfo;
}
- 1
上面的代码通过模拟从数据库获取数据设置到ActiveUser中。
修改FirstAction中的first方法
修改代码将获取身份信息,并放入request域中用于页面显示。
//系统首页
@RequestMapping("/first")
public String first(Model model)throws Exception{
Subject subject =SecurityUtils.getSubject();
ActiveUser activeUser = (ActiveUser)subject.getPrincipal();
model.addAttribute("activeUser", activeUser);
return "/first";
}
测试
在登录界面,账号输入 zhangsan , 密码输入 123
如果成功的话,将会看到如下页面。 
shiro过滤器总结
| 过滤器简称 | 对应的Java类 |
|---|---|
| anon | org.apache.shiro.web.filter.authc.AnonymousFilter |
| authc | org.apache.shiro.web.filter.authc.FormAuthenticationFilter |
| authcBasic | org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter |
| perms | org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter |
| port | org.apache.shiro.web.filter.authz.PortFilter |
| rest | org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter |
| roles | org.apache.shiro.web.filter.authz.RolesAuthorizationFilter |
| ssl | org.apache.shiro.web.filter.authz.SslFilter |
| user | org.apache.shiro.web.filter.authc.UserFilter |
| logout | org.apache.shiro.web.filter.authc.LogoutFilter |
各个过滤器的介绍和作用:
anon:例子/admins/**=anon 没有参数,表示可以匿名使用。
authc:例如/admins/user/**=authc表示需要认证(登录)才能使用,FormAuthenticationFilter是表单认证,没有参数 。
roles:例子 /admins/user/** =roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如admins/user/** =roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。
perms:例子/admins/user/**=perms[user:add:*],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。
rest:例子/admins/user/**=rest[user],根据请求的方法,相当于/admins/user/**=perms[user:method],其中method为post,get,delete等。
port:例子/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString
是你访问的url里的?后面的参数。
authcBasic:例如/admins/user/**=authcBasic没有参数表示httpBasic认证
ssl:例子/admins/user/**=ssl没有参数,表示安全的url请求,协议为https
user:例如/admins/user/**=user没有参数表示必须存在用户, 身份认证通过或通过记住我认证通过的可以访问,当登入操作时不做检查
注:
anon,authcBasic,auchc,user是认证过滤器,
perms,roles,ssl,rest,port是授权过滤器
blog的项目地址
点击进入下载页面
(转) shiro权限框架详解06-shiro与web项目整合(上)的更多相关文章
- (转)shiro权限框架详解06-shiro与web项目整合(下)
http://blog.csdn.net/facekbook/article/details/54962975 shiro和web项目整合,实现类似真实项目的应用 web项目中认证 web项目中授权 ...
- (转)shiro权限框架详解03-shiro介绍
http://blog.csdn.net/facekbook/article/details/54893740 shiro介绍 本文正式进入主题.本文将介绍如下内容: 什么是shiro 为什么需要学习 ...
- (转)shiro权限框架详解05-shiro授权
http://blog.csdn.net/facekbook/article/details/54910606 本文介绍 授权流程 授权方式 授权测试 自定义授权realm 授权流程 开始构造Secu ...
- (转)shiro权限框架详解02-权限理论介绍
http://blog.csdn.net/facekbook/article/details/54893042 权限管理解决方案 本文主要介绍权限管理的解决方法: 粗颗粒度和细颗粒度 基于url拦截 ...
- (转) shiro权限框架详解04-shiro认证
http://blog.csdn.net/facekbook/article/details/54906635 shiro认证 本文介绍shiro的认证功能 认证流程 入门程序(用户登录和退出) 自定 ...
- (转)shiro权限框架详解01-权限理论介绍
http://blog.csdn.net/facekbook/article/details/54890365 权限管理 本文介绍权限管理的理论和权限管理的一些名词. 介绍权限管理 理解身份认证和授权 ...
- Shiro 安全框架详解二(概念+权限案例实现)
Shiro 安全框架详解二 总结内容 一.登录认证 二.Shiro 授权 1. 概念 2. 授权流程图 三.基于 ini 的授权认证案例实现 1. 实现原理图 2. 实现代码 2.1 添加 maven ...
- Shiro 安全框架详解一(概念+登录案例实现)
shiro 安全框架详细教程 总结内容 一.RBAC 的概念 二.两种常用的权限管理框架 1. Apache Shiro 2. Spring Security 3. Shiro 和 Spring Se ...
- Shiro权限管理框架详解
1 权限管理1.1 什么是权限管理 基本上涉及到用户参与的系统都要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以访问而且只能访问自己被 ...
随机推荐
- SSO 单点登录解决方案
转自:http://www.blogjava.net/Jack2007/archive/2014/03/11/191795.html 1 什么是单点登陆 单点登录(Single Sign O ...
- (C/C++学习)1.C++中vector的使用
说明:vector是C++中一个非常方便的容器类,它用于存放类型相同的元素,利用成员函数及相关函数可以方便的对元素进行增加或删除,排序或逆序等等,下面将对这些功能一一叙述. 一.vector的第一种用 ...
- 3.在eclipse中创建Web项目,并部署到Tomcat上
1.找到创建web项目的菜单 2.创建web项目并选择web环境 3.查看创建好的web项目结构 4.在web项目的webContent文件夹下创建jsp页面 5.查看是否创建jsp页面成功,并编辑j ...
- 0419MySQL 中 Join 的基本实现原理
转自http://www.kuqin.com/database/20081206/29717.html 简朝阳 JOIN的用法你真的知道吗? 在 MySQL 中,只有一种 Join 算法,就是大名鼎鼎 ...
- SVN提示被锁定的解决方法(转)
1.(常用)出现这个问题后使用“清理”即"Clean up"功能,如果还不行,就直接到上一级目录,再执行“清理”,然后再“更新”. 2.(没试过)有时候如果看到某个包里面的文件夹没 ...
- jdbc 读取oracle long raw 字段,里面存的是文本
jdbc 读取oracle long raw 字段,里面存的是文本 参考: http://singlewolf.iteye.com/blog/278769 http://blog.csdn.net/r ...
- Python标准库:内置函数range(stop) range(start, stop[, step])
本函数是产生一系列序列的数组,返回迭代子.參数stop是终止的数字:參数start是指明開始数列開始值:參数step是数列之间的差值. 因此这个函数就是产生以start为起点.以stop为终点,以st ...
- C++:探究纯虚析构函数以及实现数组的高速排序与链表的归并排序
C++:探究纯虚析构函数以及实现数组的高速排序与链表的归并排序 标签: 数据结构 数组 链表 高速排序 归并排序 抽象类 虚继承 by 小威威 1.介绍 本篇博文将通过课后作业的(15 C++ Hom ...
- 判断是否是pc,获取屏幕宽度
$(function(){ var w=document.documentElement?document.documentElement.clientWidth:document.body.clie ...
- sikuli类、函数使用参考java doc
sikuli类.函数使用可以参考java dochttp://doc.sikuli.org/javadoc/ http://stackoverflow.com/questions/9568612/s ...