zoukankan      html  css  js  c++  java
  • shiro动态控制url资源

    怎么利用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()) +"
    ";
                }//追加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()) +"
    ";
                    }//追加beans.xml中已经有的过滤
                }
            }
            
            //对url拦截
            fiter += "/**"+" = authc" +"
    ";
            //fiter+="/test/add.html"+" = authc," +MessageFormat.format(PREMISSION_STRING,"/test/add.html") +"
    ";
            //fiter+="/js/**"+" = authc," +MessageFormat.format(PREMISSION_STRING,"/js/**") +"
    ";
            //fiter+="/js/**"+" = " +MessageFormat.format(PREMISSION_STRING,"/js/**") +"
    ";
            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)保存在数据库中。

  • 相关阅读:
    简单的sql注入3
    简单的sql注入2
    简单的sql注入1
    python安装request及更新pip
    kali linux上安装ssh
    看起来有点难
    猫抓老鼠
    头有点大
    貌似有点难
    这个看起来有点简单!
  • 原文地址:https://www.cnblogs.com/super-chao/p/8758763.html
Copyright © 2011-2022 走看看