SSM整合shiro权限框架
一、SSM整合shiro框架
1.步驟
1.添加shiro框架需要的jar包,包括shiro-core、shiro-web、shiro-spring的關系依賴
? ? ? ?<!-- shiro jar包依賴 --><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>${shiro.version}</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-web</artifactId><version>${shiro.version}</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>${shiro.version}</version></dependency>2.在web.xml文件中配置shiro的過濾器
<!-- 配置shiro框架的過濾器 --><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><!-- 添加字符集過濾器 --><filter><filter-name>encoding</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>encoding</filter-name><url-pattern>/*</url-pattern></filter-mapping>3.添加applicationContext.shiro.xml文件,添加在web.xml中filter對應的spring容器對應的bean
4.靜態資源處理
<!-- web.xml中shiro的filter對應的bean --><!-- Shiro 的Web過濾器 --><bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><property name="securityManager" ref="securityManager" /><!-- loginUrl認證提交地址,如果沒有認證將會請求此地址進行認證,請求此地址將由formAuthenticationFilter進行表單認證 --><property name="loginUrl" value="/login.do" /><!-- 認證成功統一跳轉到first.action,建議不配置,shiro認證成功自動到上一個請求路徑 --><property name="successUrl" value="/index.do" /><!-- 通過unauthorizedUrl指定沒有權限操作時跳轉頁面 --><property name="unauthorizedUrl" value="/nofunc.jsp" /> ?<!-- 過慮器鏈定義,從上向下順序執行,一般將/**放在最下邊 --><property name="filterChainDefinitions"><value><!-- 對靜態資源設置匿名訪問 -->/static/* = anon/login.do = anon/toLogin.do=anon<!-- 過濾器對資源進行驗證 -->/index.do = authc<!-- 請求 logout地址,shiro去清除session -->/logout.do = logout<!-- 具有指定的權限才能訪問 -->/userManager.do = perms[user:manager]/roleManager.do = perms[role:manager]/toUserRole.do = perms[user:pression]<!-- /* = authc 所有url都必須認證通過才可以訪問 -->/* = authc</value></property></bean><!-- securityManager安全管理器 --><bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><property name="realm" ref="authenRealm" /></bean><!-- realm --><bean id="authenRealm" class="com.demo.realm.AuthenRealms"><!-- 將憑證匹配器設置到realm中,realm按照憑證匹配器的要求進行散列 --><property name="credentialsMatcher" ref="credentialsMatcher" /></bean><!-- 憑證匹配器 --><bean id="credentialsMatcher"class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"><property name="hashAlgorithmName" value="md5" /><property name="hashIterations" value="1" /></bean>5.自定義AuthenRalms
public class AuthenRealms extends AuthorizingRealm { ?@ResourceIUserService userService;@ResourceIFunctionService functionService;/*** 授權方法*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {//獲取當前用戶信息User user = (User)principals.getPrimaryPrincipal();List<String> perms = new ArrayList<String>();//List<String> roles = new ArrayList<String>();//根據用戶信息獲取所屬于角色//根據角色查權限List<Function> functions = functionService.findByUserId(user.getUserId());for(Function func : functions){perms.add(func.getFuncCode());}SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();//把所有的權限串列表都放到SimpleAuthorizationInfo對象中authorizationInfo.addStringPermissions(perms); //authorizationInfo.addRoles(roles);//放置所有的角色信息return authorizationInfo;}/*** 認證方法*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {//獲取用戶名名稱String username = token.getPrincipal().toString();//通過用戶名獲取用戶對象User user = userService.login(username, null);//把user對象封裝的AuthenticationInfo中返回SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user,user.getPassword(),ByteSource.Util.bytes(user.getSalt()),"authenRealm");return authenticationInfo;} ? }6.登陸
@RequestMapping("/login.do")public String login(String username,String password,HttpServletRequest request){//當用戶名稱和密碼都不為空的情況下,通過用戶名和密碼進行數據庫查詢校驗//獲取當前的主體對象Subject subject = SecurityUtils.getSubject();//創建用戶登錄驗證令牌UsernamePasswordToken token = new UsernamePasswordToken(username,password);try {subject.login(token);boolean flag = subject.isAuthenticated();if(flag){ //驗證通過//把用戶對象信息放入到session中User user = (User)subject.getPrincipal();subject.getSession().setAttribute("user",user);return "success";}else{return "login";}} catch (Exception e) {e.printStackTrace();return "login";}}二、實現shiro框架的授權
1.基于xml配置文件的授權
在applicationContext-shiro中配置
<!-- 具有指定的權限才能訪問 --> /userManager.do = perms[user:manager] /roleManager.do = perms[role:manager] /toUserRole.do = perms[user:pression]2.基于注解方式的授權
在springmvc配置文件中添加shiro注解的支持和spring aop代理的支持
<!-- 開啟aop,對類代理 --><aop:config proxy-target-class="true"></aop:config><!-- 開啟shiro注解支持 --><beanclass="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"><property name="securityManager" ref="securityManager"></property></bean>在控制器上添加權限驗證的注解
//需要具有function:manager權限,才能執行該控制器方法 @RequiresPermissions(value={"function:manager"})@RequestMapping("/functionManager.do")public String functionManager() {return "success";}3.基于jsp頁面標簽的授權
jsp頁面添加
<%@ taglib uri ="http://shiro.apache.org/tags" prefix="shiro"%>常見標簽:
| shiro:authenticated | 登陸之后 |
| shiro:notAuthenticated | 沒有登陸 |
| shiro:guest | 用戶在沒有RemberMe時 |
| shiro:user | 用戶在RemberMe時 |
| <shiro:hasAnyRoles name="admin,user"> | 在有admin和user角色時 |
| <shiro:hasRole name="admin"> | 擁有角色admin |
| <shiro:lacksRole name="admin"> | 沒有角色admin |
| <shiro:hasPermission name="abc"> | 擁有權限資源abc |
| <shiro:lacksPermission name="abc"> | 沒有abc權限資源 |
| shiro:principal | 顯示用戶身份名稱 |
| <shiro:principal property="username"> | 顯示用戶身份中的屬性值 |
4.退出操作
在shiro.xml配置文件中配置退出過濾器,shiro自動完成系統的退出操作
<!-- 過慮器鏈定義,從上向下順序執行,一般將/**放在最下邊 --> <property name="filterChainDefinitions"><value>.../logout.do = logout...</value> </property>在前端頁面直接調用logout.do即可銷毀session退出系統
<script type="text/javascript">function logoutSys(){document.location.href="logout.do";} </script> ?<input type="button" name="btn" value="退出" onclick="logoutSys()">三、shiro集成緩存管理
1.緩存的流程
-
shiro中提供了對認證信息和授權信息的緩存,shiro默認是關閉認證信息緩存的。對于授權信息的緩存shiro默認是開啟的,因為授權信息的數據量比較大,所以我們要對授權信息進行緩存
-
shiro每次授權都會通過realm獲取權限信息,為了提高訪問速度需要添加緩存。第一次從realm中讀取權限數據,之后不再讀取
2.具體步驟
(1)導入ehcache插件的依賴
? ? ? ?<!-- 緩存依賴 --><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-ehcache</artifactId><version>${shiro.version}</version></dependency>(2)applicationContext-shiro.xml中添加配置信息
<!-- 緩存的配置 --><bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"><property name="cacheManagerConfigFile" value="classpath:shiro-ehcache.xml" /></bean> ?<!-- session管理器 --><bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"><!-- 配置session的失效時長,單位是毫秒 --><property name="globalSessionTimeout" value="100000"></property><!-- 刪除失效的session --><property name="deleteInvalidSessions" value="true"></property></bean>(3)添加shiro-ehcache.xml配置文件
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="../config/ehcache.xsd"><!--diskStore:緩存數據持久化的目錄 地址 --><diskStore path="E:\workspace\ehcache" /><defaultCache maxElementsInMemory="1000" maxElementsOnDisk="10000000"eternal="false" overflowToDisk="false" diskPersistent="false"timeToIdleSeconds="120"timeToLiveSeconds="120" diskExpiryThreadIntervalSeconds="120"memoryStoreEvictionPolicy="LRU"></defaultCache> </ehcache>3.清除緩存
-
用戶正常退出后,shiro框架會自動清除緩存信息
-
高版本的shiro框架,用戶非正常登陸也會自動清除緩存信息
-
當用戶權限修改后,用戶再次登陸shiro會自動調用realm從數據庫獲取權限數據,如果在修改權限后向立即清除緩存可以調用realm的clearCache方法手動清除緩存
自定義realm類中定義如下方法:
/*** 清除緩存*/public void clearCache(){//獲取當前主體對象PrincipalCollection ?principal = SecurityUtils.getSubject().getPrincipals();super.clearCache(principal); //清除緩存}修改權限數據后,調用該方法
@Service public class UserServiceImpl implements IUserService {@ResourceAuthenRealms authenRealms;@ResourceIUserDao userDao; ?public int updateUser(User user){int result = userDao.updateByPrimaryKey(user);//調用清除緩存的方法authenRealms.clearCache();return result;} }?
總結
以上是生活随笔為你收集整理的SSM整合shiro权限框架的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: shiro权限框架
- 下一篇: SSM整合shiro框架相关配置文件