怎么利用shiro权限动态控制每个url资源呢?主要包括jsp(html)页面、action的url访问,而静态资源和登录资源则可直接访问。
所谓动态控制url就是url的权限控制不是手动写死在配置文件中,而是根据数据库的变化而变化。
表结构:
user2:用户表
t_role:角色表
t_user_role:用户角色表
t_privilege:权限资源表
t_role_privilege:角色权限资源表
shiro动态控制url资源:
applicationContext-shiro.xml配置chainDefinitionSectionMetaSource:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:util="http://www.springframework.org/schema/util" ??????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ??????xmlns:p="http://www.springframework.org/schema/p" ??????xsi:schemaLocation=" ??????http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd ??????http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> ???<description>apache shiro配置</description> ???????<bean id="chainDefinitionSectionMetaSource" class="com.test.www.web.filter.ChainDefinitionSectionMetaSource"> ???????<property name="filterChainDefinitions"> ??????????????<value> ??????????????????<!-- 静态资源允许访问 --> ???????????????<!-- /** = anon --> ???????????????<!-- /app/** = anon ???????????????/assets/** = anon --> ???????????????<!-- 登录页允许访问 --> ??????????????????<!-- ?/user/login.htm = anon --> ???????????????<!-- /login.jsp = anon ?--> ???????????????<!-- /*.jsp = anon --> ???????????????<!-- /js/**=anon --> ???????????????<!-- 登录页面 --> ???????????????/index2.jsp = anon ???????????????/js/** = anon ???????????????/css/** = anon ???????????????/images/** = anon ???????????????/assets/** = anon ???????????????/test/loginAdmin.html=anon ???????????????/logout=logout ?<!-- 这才是对退出的配置 --> ????????????????<!-- /test/add.html = perms["user:add"] --> ?????????????????????<!-- /test/add.html = perms["/test/add.html"] --> ???????????????<!-- 其他资源需要认证 --> ???????????????<!-- /** = authc --> ???????????????<!-- /logout=logout --> ?<!-- 这才是对退出的配置,不能放在/** = authc的后面 --> ????????????????????????????</value> ???????</property> ???</bean> ???????<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> ???????<property name="filters"> ???????????<map> ???????????????<entry key="logout" value-ref="logoutFilter"/> ???????????</map> ???????</property> ???????<property name="securityManager" ref="securityManager"/> ??????<!-- ?<property name="loginUrl" value="/index2.jsp"/> ???????<property name="successUrl" value="/main/main.htm"/> ???????<property name="unauthorizedUrl" value="/page/401.htm"/> --> ???????<!-- shiro判断是否登录,没有登录则跳转到登录页面,loginUrl对应登录页面的路径 --> ???????<property name="loginUrl" value="/index2.jsp"/> ???????<property name="unauthorizedUrl" value="/page/401.htm"/><!-- /page/401.htm --> ???????????????<property name="filterChainDefinitionMap" ref="chainDefinitionSectionMetaSource" /> ???</bean> ???<!-- 缓存管理器 使用Ehcache实现 --> ???<!-- ????<bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager" p:cacheManagerConfigFile="/WEB-INF/conf/ehcache-shiro.xml"> ???</bean> ????--> ???<!-- 会话DAO --> ???<bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.MemorySessionDAO"/> ???<!-- 会话管理器 --> ???<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> ???????<property name="sessionDAO" ref="sessionDAO"/> ???</bean> ???<!-- 安全管理器 --> ???<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> ???????<property name="realms"> ???????????<list> ???????????????<ref bean="securityRealm"/> ???????????</list> ???????</property> ???????<!-- cacheManager,集合spring缓存工厂 --> ???????<!-- <property name="cacheManager" ref="shiroEhcacheManager" /> ???????<property name="sessionManager" ref="sessionManager" /> --> ???</bean> ???<!-- Shiro生命周期处理器 --> ???<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/></beans>
ChainDefinitionSectionMetaSource.java:
package com.test.www.web.filter;import java.text.MessageFormat;import java.util.List;import javax.annotation.Resource;import org.apache.commons.lang3.StringUtils;import org.apache.shiro.config.Ini;import org.apache.shiro.config.Ini.Section;import org.springframework.beans.factory.FactoryBean;import com.test.www.web.entity.user.TPrivilege;import com.test.www.web.service.user.TPrivilegeService;public class ChainDefinitionSectionMetaSource implements FactoryBean<Ini.Section>{public static final String PREMISSION_STRING="perms[\"{0}\"]"; ???????private String filterChainDefinitions; ???????/*private PrivilegeDao privilegeDao; ???public PrivilegeDao getPrivilegeDao() { ???????return privilegeDao; ???}*/ ???????@Resource ???private TPrivilegeService tPrivilegeService; ???????public String getFilterChainDefinitions() { ???????return filterChainDefinitions; ???} ???????@Resource ???public void setFilterChainDefinitions(String filterChainDefinitions) { ???????String fiter="";//改正后的url配置 ???????/*List<Privilege> list = privilegeDao.getAll(); ???????for (Iterator<Privilege> it = list.iterator(); it.hasNext();) { ???????????Privilege privilege = it.next(); ???????????if(!StringUtils.isEmpty(privilege.getUrl())) { ???????????????fiter+="/"+privilege.getUrl()+" = authc," +MessageFormat.format(PREMISSION_STRING,privilege.getPerms()) +"\n"; ???????????}//追加beans.xml中已经有的过滤 ???????}*/ ???????????????List<TPrivilege> tPrivilegeList = tPrivilegeService.selectAllPrivileges(); ???????if(tPrivilegeList!=null && tPrivilegeList.size()>0){ ???????????for (TPrivilege tPrivilege : tPrivilegeList) { ???????????????if(!StringUtils.isEmpty(tPrivilege.getUrl())) { ???????????????????fiter += tPrivilege.getUrl()+" = authc," +MessageFormat.format(PREMISSION_STRING,tPrivilege.getUrl()) +"\n"; ???????????????}//追加beans.xml中已经有的过滤 ???????????} ???????} ???????????????//对url拦截 ???????fiter += "/**"+" = authc" +"\n"; ???????//fiter+="/test/add.html"+" = authc," +MessageFormat.format(PREMISSION_STRING,"/test/add.html") +"\n"; ???????//fiter+="/js/**"+" = authc," +MessageFormat.format(PREMISSION_STRING,"/js/**") +"\n"; ???????//fiter+="/js/**"+" = " +MessageFormat.format(PREMISSION_STRING,"/js/**") +"\n"; ???????System.out.println(filterChainDefinitions+fiter); ???????this.filterChainDefinitions = filterChainDefinitions+fiter; ???} ???/*@Resource ???public void setPrivilegeDao(PrivilegeDao privilegeDao) { ???????this.privilegeDao = privilegeDao; ???}*/ ???????public Section getObject(){ ???????Ini ini = new Ini();//网上好多都是在这里配置URL的。但是发现是错误的。 ???????ini.load(filterChainDefinitions); ???????Ini.Section section = ini.getSection(Ini.DEFAULT_SECTION_NAME); ???????return section; ???} ???public Class<?> getObjectType() { ???????return this.getClass(); ???} ???public boolean isSingleton() { ???????return false; ???}}
服务器启动的时候会执行ChainDefinitionSectionMetaSource类,加载系统权限资源表所有的url到filterChainDefinitions中(在filterChainDefinitions后追加),从而实现对所有url资源的权限控制的配置:
这个类就是用来在filterChainDefinitions中追加url资源权限控制的。
注意:
/** = authc应放在最后,否则会影响追加的权限资源的控制。
当访问资源的时候,例如/test/toAddUser.html,就会进入shiro授权方法中进行权限校验,如果没有权限则进入到401未授权,否则正常访问。
SecurityRealm.java:
package com.test.www.web.security;import java.util.List;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.SimpleAuthenticationInfo;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 org.apache.shiro.subject.Subject;import org.springframework.stereotype.Component;import com.test.www.web.entity.user.TRolePrivilegeKey;import com.test.www.web.entity.user.TUserRoleKey;import com.test.www.web.entity.user.User;import com.test.www.web.service.user.TRolePrivilegeService;import com.test.www.web.service.user.TUserRoleService;import com.test.www.web.service.user.UserService;/** * 用户身份验证,授权 Realm 组件 * ?**/@Component(value = "securityRealm")public class SecurityRealm extends AuthorizingRealm { ???@Resource ???private UserService userService; ???@Resource ???private TUserRoleService tUserRoleService; ???@Resource ???private TRolePrivilegeService tRolePrivilegeService; ???/** ????* 权限检查 ????*/ ???@Override ???protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { ???????/*SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); ???????String username = String.valueOf(principals.getPrimaryPrincipal()); ???????System.out.println("ssssssss");*/ ???????String username = principals.getPrimaryPrincipal().toString() ; ???????System.out.println(username); ???????????????Subject subject = SecurityUtils.getSubject(); ???????User user = (User)subject.getPrincipal(); ???????????????SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo() ; ???????????????/*Set<String> roleName = t_userService.findRoles(username) ; ???????Set<String> permissions = t_userService.findPermissions(username) ;*/ ???????//final List<Role> roleInfos = roleService.selectRolesByUserId(user.getUserId()); ???????/*for (Role role : roleInfos) { ???????????// 添加角色 ???????????System.err.println(role); ???????????authorizationInfo.addRole(role.getRoleSign()); ???????????final List<Permission> permissions = permissionService.selectPermissionsByRoleId(role.getRoleId()); ???????????for (Permission permission : permissions) { ???????????????// 添加权限 ???????????????System.err.println(permission); ???????????????authorizationInfo.addStringPermission(permission.getPermissionSign()); ???????????} ???????}*/ ???????????????List<TUserRoleKey> tUserRoleKeyList = tUserRoleService.selectRolesByUserId(user.getId()); ???????if(tUserRoleKeyList != null && tUserRoleKeyList.size()>0){ ???????????for(TUserRoleKey tUserRoleKey : tUserRoleKeyList){ ???????????????authorizationInfo.addRole(tUserRoleKey.getCode()); ???????????????List<TRolePrivilegeKey> tRolePrivilegeKeyList = tRolePrivilegeService.selectPrivilegesByRoleId(tUserRoleKey.getRoleId()); ???????????????for(TRolePrivilegeKey tRolePrivilegeKey : tRolePrivilegeKeyList){ ???????????????????authorizationInfo.addStringPermission(tRolePrivilegeKey.getUrl()); ???????????????} ???????????} ???????} ???????//Set<String> roleName = new HashSet<String>(); ???????//Set<String> permissions = new HashSet<String>(); ???????//查询角色 ???????//roleName.add("admin"); ???????//根据角色查询权限 ???????//permissions.add("/test/add.html1"); //pub:coursecategory user:add ???????//permissions.add("/js/**"); ???????//permissions.add("/jsp"); ???????//authorizationInfo.setRoles(roleName); ???????//authorizationInfo.setStringPermissions(permissions); ???????return authorizationInfo; ???} ???/** ????* 登录验证 ????*/ ???@Override ???protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { ???????/* String username = String.valueOf(token.getPrincipal()); ???????String password = new String((char[]) token.getCredentials()); ???????System.out.println("aaaaaaa"); ???????SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, password, getName());*/ ???????//int i = 1/0; ???????????????//获取用户账号 ???????//验证账号密码 ???????UsernamePasswordToken userToken = (UsernamePasswordToken) token; ???????System.out.println("1:"+userToken.getUsername()); ???????User user = userService.getUserByUserName(userToken.getUsername()); ???????System.out.println("2"); ???????if (user != null){ ???????????//将查询到的用户账号和密码存放到 authenticationInfo用于后面的权限判断。第三个参数传入realmName。 ???????????AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user,user.getPassword(),this.getClass().getSimpleName()) ; ???????????return authenticationInfo ; ???????}else{ ???????????return ?null ; ???????} ???}}
至此,shiro动态控制url权限资源已完成。
说明:
url资源(action、静态html或动态页面jsp的url)保存在数据库中。
shiro动态控制url资源
原文地址:https://www.cnblogs.com/super-chao/p/8758763.html