web开发中spring集成shiro进行权限管理
来源:互联网 发布:电子商务网络推广 编辑:程序博客网 时间:2024/06/08 18:16
权限管理是一个系统不可缺少的一部分,也是比较复杂的一部分。
目前有二个主流权限管理的框架:shiro 和spring security ,以下讲解spring如何集成apache shiro
第一步:导入shiro的jar包
shiro-aspectj-1.2.2.jar
shiro-cas-1.2.2.jar
shiro-core-1.2.2.jar
shiro-ehcache-1.2.2.jar
shiro-guice-1.2.2.jar
shiro-quartz-1.2.2.jar
shiro-spring-1.2.2.jar
shiro-tools-hasher-1.2.2-cli.jar
shiro-web-1.2.2.jar
第二步:编写自己的Realm实现类:
package com.bs.common.shiro.realm;import java.io.Serializable;import java.util.HashSet;import java.util.Set;import javax.annotation.Resource;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.IncorrectCredentialsException;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authc.UnknownAccountException;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import com.bs.exception.BsException;import com.bs.exception.BsExceptionCode;import com.bs.system.po.BookUserInfo;import com.bs.system.service.IBookUserService;public class MyRealm extends AuthorizingRealm {@Resource(name="bookUserService")private IBookUserService bookUserService;/** * 授权 */@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {//arg0.getPrimaryPrincipal(): 实际上是在认证时返回的 SimpleAuthenticationInfo 的第一个参数! // Object principal = arg0.getPrimaryPrincipal(); // ShiroUser user = (ShiroUser) principal; ShiroUser user = (ShiroUser) SecurityUtils.getSubject().getSession().getAttribute("userObj"); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.setRoles(user.getRoles()); info.setStringPermissions(user.getPermissions()); return info; }/** * 认证 */@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {//强转为UsernamePasswordToken类型 UsernamePasswordToken token=(UsernamePasswordToken)arg0; //获取用户名和密码(密码要转为字符串类型) String username = token.getUsername(); String password = new String(token.getPassword()); //测试一下,看是否得到了用户名和密码 System.out.println("username: " + username + ", password: " + password); BookUserInfo bookUserInfo = null; try { bookUserInfo = bookUserService.loginService(username, password); if(bookUserInfo==null){ throw new IncorrectCredentialsException("密码错误"); }} catch(BsException bs){if(BsExceptionCode.ERROR_CODE_NO_DATA==bs.getErrorCode()){throw new UnknownAccountException("账户不存在,请联系管理员!");}} //利用新建的类来创建对象 ShiroUser user=new ShiroUser(); user.setUsername(username); //将页面中的username值设置进去 //模拟设置权限部分 //实际项目中:从数据库根据用户名去查询其角色和权限 if("admin".equals(username)){ //如果用户名为:admin,则为其增加2个角色 admin和user //这里是模拟设置角色 user.getRoles().add("admin"); user.getRoles().add("user"); Set<String> permissions = new HashSet<String>(); //这里是模拟设置权限 permissions.add("book:add"); permissions.add("book:create"); user.setPermissions(permissions); }else { //如果用户名不为admin,则为其增加user角色 user.getRoles().add("user"); } SecurityUtils.getSubject().getSession().setAttribute("userObj", user); return new SimpleAuthenticationInfo(username, password,getName()); }@Overridepublic String getName() {return "myRealm";}//新建一个类定义用户角色和权限 class ShiroUser implements Serializable{ private static final long serialVersionUID = 1L; private String username; private Set<String> roles= new HashSet<String>(); private Set<String> permissions = new HashSet<String>(); public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Set<String> getRoles() { return roles; } public void setRoles(Set<String> roles) { this.roles = roles; }public Set<String> getPermissions() {return permissions;}public void setPermissions(Set<String> permissions) {this.permissions = permissions;} } }
第三步:在src目录下新建applicationContext-shiro.xml配置文件内容如下:
<?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:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:util="http://www.springframework.org/schema/util"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsdhttp://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!--2.配置CacheManager实例:管理Shiro相关缓存操作 --> <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> <property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml"></property> </bean> <!--3.配置realm实例,实际的认证和授权都是由Realm实例来完成的! --> <bean id="myRealm" class="com.bs.common.shiro.realm.MyRealm"></bean> <!-- 4.配置 SecurityManager 实例. SecurityManager 是 Shiro 最核心的组件 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="cacheManager" ref="cacheManager"/> <property name="realm" ref="myRealm"/> </bean> <!--5.配置bean的后置处理器来自动调用Shiro中的bean的init和destroy方法。 --> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"></bean> <!--6.配置使shiro注解起作用的bean,需要放在 lifecycleBeanPostProcessor后面 --> <aop:config proxy-target-class="true"></aop:config> <!-- <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"></bean> --> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager"></property> </bean> <!-- 7.配置哪些页面需要被拦截,以及访问这些页面所需的权限 。 该bean中的id 属性值必须和 web.xml 文件中配置的 filter 的 filter-name 值一致 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"></property> <!--①配置登陆页面 --> <property name="loginUrl" value="/index.jsp"></property> <property name="successUrl" value="/admin.jsp"></property> <property name="unauthorizedUrl" value="/index.jsp"></property> <!-- <property name="filters"> <util:map> <entry key="authc"> <bean class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter"/> </entry> </util:map> </property> --> <!--②配置需要被拦截的资源 以及访问权限 --> <property name="filterChainDefinitions"> <value> <!-- anon: 表示匿名的, 即任何人都可以访问 --> /add.jsp=anon /images/**=anon /js/**=anon /skin/**=anon /upload/**=anon /index.jsp=anon /login.jsp=anon /user/**=anon /system/**=anon /book/**=anon /login=anon /logout=logout <!--③设置访问具体资源的权限 --> /admin.jsp=roles[admin] /user.jsp=roles[user] <!-- authc 表示必须经过认证之后才可以访问的页面 --> /**=authc </value> </property> </bean> </beans>第四步:在src目录新建ehcache-shiro.xml配置文件,内容如下:
<ehcache> <diskStore path="java.io.tmpdir/shiro-spring-sample"/> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="false" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" /> <cache name="shiro-activeSessionCache" maxElementsInMemory="10000" eternal="true" overflowToDisk="true" diskPersistent="true" diskExpiryThreadIntervalSeconds="600"/> <cache name="org.apache.shiro.realm.SimpleAccountRealm.authorization" maxElementsInMemory="100" eternal="false" timeToLiveSeconds="600" overflowToDisk="false"/> </ehcache>第五步:修改web.xml配置文件:
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml,classpath:applicationContext-shiro.xml</param-value> </context-param>配置shiro过滤器:需要配置在struts2或者springmvc框架的拦截配置之前
<!--配置shiro过滤器 --> <filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <init-param> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
至此,spring集成shiro配置完毕。
编写登陆的处理方法:
public String login(){//数据验证if(ObjectFormatUtil.isNotNull(username) && ObjectFormatUtil.isNotNull(password)){try {//1.获取当前的用户 Subject currentUser = SecurityUtils.getSubject(); //2.把登录信息封装为一个 UsernamePasswordToken 对象 UsernamePasswordToken token=new UsernamePasswordToken(this.username,this.password); currentUser.login(token); } catch (UnknownAccountException uae) { System.out.println("用户名不存在: " + uae); return "input"; } catch (IncorrectCredentialsException ice) { System.out.println("用户名存在,但密码和用户名不匹配: " + ice); return "input"; } catch (LockedAccountException lae) { System.out.println("用户被锁定: " + lae); return "input"; } catch (AuthenticationException ae) { System.out.println("其他异常: " + ae); return "input"; } }else{message = "用户名或密码不能为空";}return "main";}
编程退出登录方法:
public String loginout(){//移除sessionSubject currentUser = SecurityUtils.getSubject(); currentUser.logout();return "loginPage";}
shiro标签的使用:
以下配置表示:拥有admin角色的用户可以显示图书管理和系统管理菜单
<%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro" %><shiro:hasRole name="admin"><dd><div class='item' id='item8' onMouseMove="mv(this,'m',8);" onMouseOut="mv(this,'o',8);"><a href="${ctx}/jsp/main/user/bookmenu.jsp" onclick="changeSel(8)" target="menu">图书管理</a></div></dd><dd><div class='item' id='item4' onMouseMove="mv(this,'m',4);" onMouseOut="mv(this,'o',4);"><a href="${ctx}/jsp/main/user/usermenu.jsp" onclick="changeSel(4)" target="menu">系统管理</a></div></dd></shiro:hasRole>
使用注解配置action类中方法访问的权限:
以下注解表示拥有admin角色的用户可以访问该方法:
/** * 添加分馆 * @return */@RequiresRoles({"admin"})public String doAdd(){try { if(!ObjectFormatUtil.isNotNull(bookLib.getLibname())){message = "输入的信息有误";return MESSAGE;}if(null==bookLibService.save(bookLib)){message = "保存信息失败";return MESSAGE;}return list();} catch (Exception e) {e.printStackTrace();}return "message";}
当没有权限访问以下action类的方法时,会抛出org.apache.shiro.authz.UnauthorizedException异常,我们需要在struts2中进行该异常处理:
<global-results><result name="permissionmessage">/jsp/common/permissionmessage.jsp</result></global-results><global-exception-mappings> <exception-mapping result="permissionmessage" exception="org.apache.shiro.authz.UnauthorizedException"> </exception-mapping> </global-exception-mappings>
如果使用ajax异步访问我们action类中方法时,如果没有权限,我们该怎样处理了?
如:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%><c:set var="ctx" value="${pageContext.request.contextPath}"></c:set><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <base href="<%=basePath%>"> <title>add page</title><script type="text/javascript" src="${ctx}/js/jquery-2.1.1.min.js"></script><script type="text/javascript">function add(){$.ajax({url:"${ctx}/system/testBookLib.action",type:"post",data:{"bookLib.libname":$("#libname").val()},dataType:"json",success:function(data){if(data.result){alert("添加成功");}else{alert(data.message);}}});}</script> </head> <body> 图书馆名称:<input type="text" name="libname" id="libname"/> <br> <input type="button" value="添加" id="btn_add" onclick="add()"/> </body></html>
1、我们可以使用以下方式:
public void test1(){boolean result = false;Subject subject = SecurityUtils.getSubject(); if(subject.hasRole("admin")){//1验证数据if(!ObjectFormatUtil.isNotNull(bookLib.getLibname())){message = "输入的信息有误";}//2验证图书名称是否已存在 如果已存在 则添加失败 给出提示 反正添加成功if(bookLibService.isExistBooklibName(bookLib.getLibname())){if(null==bookLibService.save(bookLib)){message = "保存信息失败";}else{result = true;}}else{message = "图书名称已存在";}}else{message ="无权访问";}outJsonString(response, "{\"result\":"+result+",\"message\":\""+message+"\"}");}
0 0
- web开发中spring集成shiro进行权限管理
- Spring集成Shiro权限管理
- Shiro集成spring--权限管理
- 【Shiro权限管理】3.Shiro集成 Spring
- 如何在spring项目中使用shiro进行权限管理
- Spring+Mybatis+Shiro开发权限管理系统
- Shiro权限控制框架 ---SpringMVC+Spring+My batis+Mysql+Maven集成开发Web项目
- Spring Boot整合jpa,Shiro进行权限管理
- 使用shiro进行权限管理
- 使用shiro进行权限管理
- 使用shiro进行权限管理
- 使用shiro进行权限管理
- Spring Boot Shiro 权限管理
- Spring Boot Shiro 权限管理
- Spring Boot Shiro权限管理
- Spring Boot Shiro 权限管理
- Spring Boot Shiro权限管理
- Spring Boot Shiro 权限管理
- Android---广播(Broadcast)---广播接收者的注册过程分析
- linux四种查找命令的方法
- 利用 Chrome 开发者工具远程调试 Android 中的原生 WebView
- python中的爬虫神器 XPath 介绍
- 常用基础命令
- web开发中spring集成shiro进行权限管理
- 将下载到本地的JAR包手动添加到Maven仓库
- Neutron的介绍
- PHP学习笔记1:基础知识及WAMPServer自定义网站根目录
- HDU2602 01背包入门 Bone Collector【01背包模板题】
- 从程序员到项目经理(9):程序员加油站 -- 再牛也要合群
- Spark --- 启动、运行、关闭过程
- [py]基础数据类型
- 限制EditText内容为.2位小数