怎样让shiro既进行角色拦截,也进行shiro url权限拦截截

width:100%">
最近精神病院在打折,楼主去看看吧?
width:100%">
width:100%">
嘘,低调。
width:100%">
记得回帖!!
width:100%">
投秀才一票,不用谢哦!
width:100%">
鄙视楼下的顶帖没我快,哈哈
width:100%">
突然觉得秀才说的很有道理,赞一个!
width:100%">
秀才说的我也略懂!
width:100%">
谢谢分享,不错不错
width:100%">
12345678910
打开手机扫一扫
Comsenz Inc. Design: Dean. DiscuzFans.Spring MVC + Shiro 实现权限验证
Spring MVC + Shiro 实现权限验证
MAVEN的pom.xml 引入shiro(Spring MVC+mybatis 请参见上一章)。
&dependency&
&groupId&org.apache.shiro&/groupId&
&artifactId&shiro-spring&/artifactId&
&version&1.2.5&/version&
&/dependency&
&!-- /artifact/org.apache.shiro/shiro-ehcache --&
&dependency&
&groupId&org.apache.shiro&/groupId&
&artifactId&shiro-ehcache&/artifactId&
&version&1.2.5&/version&
&/dependency&
&dependency&
&groupId&org.apache.shiro&/groupId&
&artifactId&shiro-core&/artifactId&
&version&1.2.5&/version&
&/dependency&
&!-- /artifact/org.apache.shiro/shiro-web --&
&dependency&
&groupId&org.apache.shiro&/groupId&
&artifactId&shiro-web&/artifactId&
&version&1.2.5&/version&
&/dependency&
web.xml 中添加shiro的过滤器
&!-- 配置Shiro过滤器,先让Shiro过滤系统接收到的请求 --&
&!-- 这里filter-name必须对应applicationContext.xml中定义的&bean id=&shiroFilter&/& --&
&!-- 使用[/*]匹配所有请求,保证所有的可控请求都经过Shiro的过滤 --&
&!-- 通常会将此filter-mapping放置到最前面(即其他filter-mapping前面),以保证它是过滤器链中第一个起作用的 --&
&filter-name&shiroFilter&/filter-name&
&filter-class&org.springframework.web.filter.DelegatingFilterProxy&/filter-class&
&init-param&
&!-- 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理 --&
&param-name&targetFilterLifecycle&/param-name&
&param-value&true&/param-value&
&/init-param&
&filter-mapping&
&filter-name&shiroFilter&/filter-name&
&url-pattern&/*&/url-pattern&
&/filter-mapping&
Spring 配置文件中添加shiro的配置
&!-- shiro config
&!-- 继承自AuthorizingRealm的自定义Realm,即指定Shiro验证用户登录的类为自定义的ShiroDbRealm.java --&
&bean id=&myRealm& class=&com.blog.shiro.entity.BaseRealm&/&
&!-- Shiro默认会使用Servlet容器的Session,可通过sessionMode属性来指定使用Shiro原生Session --&
&!-- 即&property name=&sessionMode& value=&native&/&,详细说明见官方文档 --&
&!-- 这里主要是设置自定义的单Realm应用,若有多个Realm,可使用'realms'属性代替 --&
&bean id=&securityManager& class=&org.apache.shiro.web.mgt.DefaultWebSecurityManager&&
&property name=&realm& ref=&myRealm&/&
&!-- Shiro主过滤器本身功能十分强大,其强大之处就在于它支持任何基于URL路径表达式的、自定义的过滤器的执行 --&
&!-- Web应用中,Shiro可控制的Web请求必须经过Shiro主过滤器的拦截,Shiro对基于Spring的Web应用提供了完美的支持 --&
&bean id=&shiroFilter& class=&org.apache.shiro.spring.web.ShiroFilterFactoryBean&&
&!-- Shiro的核心安全接口,这个属性是必须的 --&
&property name=&securityManager& ref=&securityManager&/&
&!-- 要求登录时的链接(可根据项目的URL进行替换),非必须的属性,默认会自动寻找Web工程根目录下的&/login.jsp&页面 --&
&property name=&loginUrl& value=&/company/admin/login.html&/&
&!-- 登录成功后要跳转的连接(本例中此属性用不到,因为登录成功后的处理逻辑在LoginController里硬编码为main.jsp了) --&
&!-- &property name=&successUrl& value=&/system/main&/& --&
&!-- 用户访问未对其授权的资源时,所显示的连接 --&
&!-- 若想更明显的测试此属性可以修改它的值,如unauthor.jsp,然后用[玄玉]登录后访问/admin/listUser.jsp就看见浏览器会显示unauthor.jsp --&
&property name=&unauthorizedUrl& value=&/admin/index.html&/&
&!-- Shiro连接约束配置,即过滤链的定义 --&
&!-- 此处可配合我的这篇文章来理解各个过滤连的作用http://blog.csdn.net/jadyer/article/details/ --&
&!-- 下面value值的第一个'/'代表的路径是相对于HttpServletRequest.getContextPath()的值来的 --&
&!-- anon:它对应的过滤器里面是空的,什么都没做,这里.do和.jsp后面的*表示参数,比方说login.jsp?main这种 --&
&!-- authc:该过滤器下的页面必须验证后才能访问,它是Shiro内置的一个拦截器org.apache.shiro.web.filter.authc.FormAuthenticationFilter --&
&property name=&filters&&
&entry key=&permission&&
&bean class=&com.blog.shiro.filters.RoleAuthorizationFilter&&
&/property&
&property name=&filterChainDefinitions&&
&!-- /admin/login=anon
/mydemo/login=anon
/mydemo/getVerifyCodeImage=anon
/main**=authc
/user/info**=authc
/admin/listUser**=authc,perms[admin:manage]
/admin/**=permission
&/property&
&!-- 保证实现了Shiro内部lifecycle函数的bean执行 --&
&bean id=&lifecycleBeanPostProcessor& class=&org.apache.shiro.spring.LifecycleBeanPostProcessor&/&
&!-- 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证 --&
&!-- 配置以下两个bean即可实现此功能 --&
&!-- Enable Shiro Annotations for Spring-configured beans. Only run after the lifecycleBeanProcessor has run --&
&!-- 由于本例中并未使用Shiro注解,故注释掉这两个bean(个人觉得将权限通过注解的方式硬编码在程序中,查看起来不是很方便,没必要使用) --&
&bean class=&org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator& depends-on=&lifecycleBeanPostProcessor&/&
&bean class=&org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor&&
&property name=&securityManager& ref=&securityManager&/&
注意:上面的com.blog.shiro.entity.BaseRealm 属于自己定制的用于登录用户的授权。com.blog.shiro.filters.RoleAuthorizationFilter是自己定义的Shiro的过滤器,进行授权验证。filterChainDefinitions用于指定要拦截URL 需特别注意的是Shiro的默认filter和自定义filter的使用。
下面贴出自己的一个简单的用户登录的权限验证的部分代码。登录页面就不贴了
首先是登录的处理方法:
@RequestMapping(value={&/admin/login&},method={RequestMethod.POST})
public String login(String username,String password, ModelMap model){
if(Checker.isEmpty(username) || Checker.isEmpty(password)){
model.put(&mesage&, &登录失败:请检查您的用户名和密码!&);
Map&String, Object& map = new HashMap&String,Object&();
map.put(&username&, username);
List&User& users = userDaoImpl.findListBy(map);
if(users.size() & 0){
User user = users.get(0);
if(user.getpassword().equals(password)){
//从SecurityUtils中取得subject
Subject subject = SecurityUtils.getSubject();
//创建Token
UsernamePasswordToken token = new UsernamePasswordToken(user.getusername(),user.getpassword());
// 使用token登录
subject.login(token);
&redirect:/admin/index.html&;
model.put(&mesage&, &登录失败:请检查您的用户名和密码!&);
model.put(&mesage&, &登录失败:请检查您的用户名和密码!&);
return &login&;
BaseRealm.java的实现
package com.blog.shiro.
import mons.lang.builder.ReflectionToStringB
import mons.lang.builder.ToStringS
import org.apache.shiro.SecurityU
import org.apache.shiro.authc.AuthenticationE
import org.apache.shiro.authc.AuthenticationI
import org.apache.shiro.authc.AuthenticationT
import org.apache.shiro.authc.SimpleAuthenticationI
import org.apache.shiro.authc.UsernamePasswordT
import org.apache.shiro.authz.AuthorizationI
import org.apache.shiro.authz.SimpleAuthorizationI
import org.apache.shiro.realm.AuthorizingR
import org.apache.shiro.session.S
import org.apache.shiro.subject.PrincipalC
import org.apache.shiro.subject.S
public class BaseRealm extends AuthorizingRealm {
* 为当前登录的Subject授予角色和权限
经测试:本例中该方法的调用时机为需授权资源被访问时
经测试:并且每次访问需授权资源时都会执行该方法中的逻辑,这表明本例中默认并未启用AuthorizationCache
个人感觉若使用了Spring3.1开始提供的ConcurrentMapCache支持,则可灵活决定是否启用AuthorizationCache
比如说这里从数据库获取权限信息时,先去访问Spring3.1提供的缓存,而不使用Shior提供的AuthorizationCache
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals){
//获取当前登录的用户名,等价于(String)principals.fromRealm(this.getName()).iterator().next()
String currentUsername = (String)super.getAvailablePrincipal(principals);
List&String& roleList = new ArrayList&String&();
List&String& permissionList = new ArrayList&String&();
//从数据库中获取当前登录用户的详细信息
User user = userService.getByUsername(currentUsername);
if(null != user){
//实体类User中包含有用户角色的实体类信息
if(null!=user.getRoles() && user.getRoles().size()&0){
//获取当前登录用户的角色
for(Role role : user.getRoles()){
roleList.add(role.getName());
//实体类Role中包含有角色权限的实体类信息
if(null!=role.getPermissions() && role.getPermissions().size()&0){
//获取权限
for(Permission pmss : role.getPermissions()){
if(!StringUtils.isEmpty(pmss.getPermission())){
permissionList.add(pmss.getPermission());
throw new AuthorizationException();
//为当前用户设置角色和权限
SimpleAuthorizationInfo simpleAuthorInfo = new SimpleAuthorizationInfo();
simpleAuthorInfo.addRoles(roleList);
simpleAuthorInfo.addStringPermissions(permissionList);
SimpleAuthorizationInfo simpleAuthorInfo = new SimpleAuthorizationInfo();
//实际中可能会像上面注释的那样从数据库取得
System.out.println(&_________________________&+currentUsername);
//添加一个角色,不是配置意义上的添加,而是证明该用户拥有admin角色
//添加权限
simpleAuthorInfo.addStringPermission(&/admin/index.html&);
simpleAuthorInfo.addStringPermission(&/admin/left.html&);
simpleAuthorInfo.addStringPermission(&/admin/info.html&);
simpleAuthorInfo.addStringPermission(&/admin/user/list.html&);
System.out.println(&已为用户[mike]赋予了[admin]角色和[admin:manage]权限&);
return simpleAuthorI
//若该方法什么都不做直接返回null的话,就会导致任何用户访问/admin/listUser.jsp时都会自动跳转到unauthorizedUrl指定的地址
//详见applicationContext.xml中的&bean id=&shiroFilter&&的配置
* 验证当前登录的Subject
经测试:本例中该方法的调用时机为LoginController.login()方法中执行Subject.login()时
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
//获取基于用户名和密码的令牌
//实际上这个authcToken是从LoginController里面currentUser.login(token)传过来的
//两个token的引用都是一样的
UsernamePasswordToken token = (UsernamePasswordToken)authcT
System.out.println(&验证当前Subject时获取到token为& + ReflectionToStringBuilder.toString(token, ToStringStyle.MULTI_LINE_STYLE));
User user = userService.getByUsername(token.getUsername());
if(null != user){
AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), user.getNickname());
this.setSession(&currentUser&, user);
return authcI
//此处无需比对,比对的逻辑Shiro会做,我们只需返回一个和令牌相关的正确的验证信息
//说白了就是第一个参数填登录用户名,第二个参数填合法的登录密码(可以是从数据库中取到的,本例中为了演示就硬编码了)
//这样一来,在随后的登录页面上就只有这里指定的用户和密码才能通过验证
AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(token.getUsername(), token.getUsername(), this.getName());
this.setSession(&currentUser&, token.getUsername());
return authcI
//没有返回登录用户名对应的SimpleAuthenticationInfo对象时,就会在LoginController中抛出UnknownAccountException异常
* 将一些数据放到ShiroSession中,以便于其它地方使用
比如Controller,使用时直接用HttpSession.getAttribute(key)就可以取到
private void setSession(Object key, Object value){
Subject currentUser = SecurityUtils.getSubject();
if(null != currentUser){
Session session = currentUser.getSession();
System.out.println(&Session默认超时时间为[& + session.getTimeout() + &]毫秒&);
if(null != session){
session.setAttribute(key, value);
注意:我这里使用的是URI来进行权限的管理,也就是说
simpleAuthorInfo.addStringPermission(&/admin/index.html&);&
&&&&&&&&&&& simpleAuthorInfo.addStringPermission(&/admin/left.html&);&
&&&&&&&&&&& simpleAuthorInfo.addStringPermission(&/admin/info.html&);&
&&&&&&&&&&& simpleAuthorInfo.addStringPermission(&/admin/user/list.html&);
这部分代码进行的是授权,意思为验证成功的用户有访问这些URI的权利 没有访问其他URI的权利,下面的filter将根据这个授权进行来开放URI给用户,
授权需根据数据库进行授权。 有时间将会有对于通用授权的实现单独写一章。
自定义filter的代码实现:
package com.blog.shiro.
import javax.servlet.ServletR
import javax.servlet.ServletR
import javax.servlet.http.HttpServletR
import org.apache.shiro.subject.S
import org.apache.shiro.web.filter.authz.AuthorizationF
public class RoleAuthorizationFilter extends AuthorizationFilter {
protected boolean isAccessAllowed(ServletRequest request,
ServletResponse response, Object object) throws Exception {
// 获取请求的资源(即请求的URI)
HttpServletRequest httpReq = (HttpServletRequest)
String uri = httpReq.getRequestURI();
//根据请求响应获取已登录的Subject对象。
Subject subject = getSubject(request, response);
// 判断登录的用户是否有此权限
return subject.isPermitted(uri);
shiro的使用异常简单方便,如有任何问题请留言。
纯属个人笔记形式,如有失误请留言指出。
我的热门文章
即使是一小步也想与你分享<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&}

我要回帖

更多关于 shiro 权限拦截器 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信