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()) +"\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)保存在数据库中。

原文地址:https://www.cnblogs.com/super-chao/p/8758763.html

时间: 2024-10-14 23:17:28

shiro动态控制url资源的相关文章

URL资源跨域访问 跨域使用session信息

SilverLight 出于对安全性的考虑默认情况下对URL的访问进行了严格的限制,只允许访问同一子域下的URL资源. 下表列出了Silverlight 2.0 中 URL 访问规则:   WebClient对象 Media.images.ASX XAML 文件.Font 文件 流媒体 允许的协议 HTTP, HTTPS HTTP, HTTPS, FILE HTTP, HTTPS, FILE HTTP 跨协议访问 不允许 不允许 不允许 不允许来自HTTPS的访问 跨Web域访问 不允许 如果不

项目一:第十二天 1、常见权限控制方式 2、基于shiro提供url拦截方式验证权限 3、在realm中授权 5、总结验证权限方式(四种) 6、用户注销7、基于treegrid实现菜单展示

1 课程计划 1. 常见权限控制方式 2. 基于shiro提供url拦截方式验证权限 3. 在realm中授权 4. 基于shiro提供注解方式验证权限 5. 总结验证权限方式(四种) 6. 用户注销 7. 基于treegrid实现菜单展示 2 常见的权限控制方式 2.1 url拦截实现权限控制 shiro基于过滤器实现的   2.2 注解方式实现权限控制 底层:代理技术     3 基于shiro的url拦截方式验权   <!-- 配置过滤器工厂 --> <bean id="

webpack处理url资源的配置

webpack处理url资源的配置 1.安装 npm i url-loader -D 2.修改webpack.config.js const path = require('path'); // 启用热更新的 第2步 const webpack = require('webpack') //导入html插件 //只要是插件,都一定要放到plugins节点中去 const htmlWebpackPlugin = require('html-webpack-plugin') // 这个配置文件,起始

[Shiro] - 基于URL配置动态权限

基于shiro进阶 更改了数据库表 之前的PageController是通过@RequiresPermissions和@RequiresRoles进行是否有权限/是否有角色的判定调用@RequestMapping路径 在PermissionService中加入了两个方法:needInterceptor, listPermissionURLs needInterceptor表示是否要进行拦截,判断依据是如果访问的某个url,在权限系统里存在,就要进行拦截. 如果不存在就放行了. 这一种策略,也可以

Shiro去掉URL上的JSESSIONID信息配置

<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> <property name="sessionIdUrlRewritingEnabled" value="false" /> </bean>

值得细细品读的URL资源

Web安全渗透方面的资源指南: 知乎综合问答:https://www.zhihu.com/question/21914899 渗透测试经典演练系统:http://www.freebuf.com/sectool/4708.html 小书屋技能树:http://www.xiaoshuwu.net/skill/ 小书屋导航:http://www.xiaoshuwu.net/navi/ 安全技能:https://www.sec-wiki.com/skill Sec-News:http://wiki.io

【shiro】关于shiro匹配URL的小用法

今天涉及到这个地方 1.登录请求需要带着username和password一起过去,这样的话发出的请求就是:http://localhost:8080/wxSecond/welcome/login.htmls?username=123&password=123 而shiro的配置中,还在担忧仅仅配置/welcome/login.htmls=anon能不能过去呢~ 结果证明: 这样的请求地址,在shiro配置中配置如下: 是完全可以的~~~~~

Shiro配置URL过滤

常用过滤器: anon     不需要认证 authc     需要认证 user     验证通过或RememberMe登录的都可以 URL说明: /admin?=authc      表示可以请求以admin开头的字符串,如xxx/adminfefe,但无法匹配多个,即xxx/admindf/admin是不行的 /admin*=authc      表示可以匹配零个或者多个字符,如/admin,/admin1,/admin123,但是不能匹配/admin/abc这种 /admin/**=au

shiro 权限 URL 配置细节

原文地址:https://www.cnblogs.com/hwgok/p/9100277.html