使用Shiro 集合Spring来实现权限控制

这只是笔记

web.xml中引入 spring-shiro.xml

spring-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:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/util
    http://www.springframework.org/schema/util/spring-util-3.0.xsd">

	<description>Shiro 配置</description>

	<!--	权限配置对照表
* @see   /admin=authc,roles[admin]      表示用户必需已通过认证,并拥有admin角色才可以正常发起'/admin'请求
数据库权限格式admin:list
* @see   /edit=authc,perms[admin:edit]  表示用户必需已通过认证,并拥有admin:edit权限才可以正常发起'/edit'请求
* @see   /home=user                     表示用户不一定需要已经通过认证,只需要曾经被Shiro记住过登录状态就可以正常发起'/home'请求
* @see   /admins/**=anon             无参,表示可匿名使用,可以理解为匿名用户或游客
* @see   /admins/user/**=authc       无参,表示需认证才能使用
* @see   /admins/user/**=authcBasic  无参,表示httpBasic认证
* @see   /admins/user/**=user        无参,表示必须存在用户,当登入操作时不做检查
* @see   /admins/user/**=ssl         无参,表示安全的URL请求,协议为https
* @see   /admins/user/**=perms[user:add:*]
* @see       参数可写多个,多参时必须加上引号,且参数之间用逗号分割,如/admins/user/**=perms["user:add:*,user:modify:*"]
* @see       当有多个参数时必须每个参数都通过才算通过,相当于isPermitedAll()方法
* @see   /admins/user/**=port[8081]
* @see       当请求的URL端口不是8081时,跳转到schemal://serverName:8081?queryString
* @see       其中schmal是协议http或https等,serverName是你访问的Host,8081是Port端口,queryString是你访问的URL里的?后面的参数
* @see   /admins/user/**=rest[user]
* @see       根据请求的方法,相当于/admins/user/**=perms[user:method],其中method为post,get,delete等
* @see   /admins/user/**=roles[admin] 参数可写多个,多个时必须加上引号,且参数之间用逗号分割,如/admins/user/**=roles["admin,guest"]
* @see       当有多个参数时必须每个参数都通过才算通过,相当于hasAllRoles()方法  -->
	<!-- 权限配置 -->
	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<property name="securityManager" ref="securityManager" />
		<property name="loginUrl" value="/direct.html" />
		<property name="successUrl" value="/index.html" />
		<property name="unauthorizedUrl" value="/403.html" /> <!-- 无权限跳转页面 -->
   		<property name="filters">
            <util:map>
                <entry key="authc">
                    <bean class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter"/>
                    <!-- <bean class="com.hbs.dipper.interceptor.MethodAuthenticationFilter"/>  -->
                </entry>
            </util:map>
        </property>
		<property name="filterChainDefinitions">
			<value>
			    <!-- 静态文件控制 -->
				/css/** = anon
				/images/** = anon
				/js/** = anon
				/index.html = user
				/direct.html = anon
				/403.html = anon
				/login.html = anon

				<!-- 用户管理权限 -->
				/user/logout = anon  <!-- 无需控制 -->
				/user/getCurrentUser = user <!-- 登陆即不做检查 -->
				/user/updatePwd = user
				/user/login/** = anon
				/user/get*/** = perms[user:view] <!-- 查看权限 -->
				/view/user/** = perms[user:view] <!-- html权限控制 -->
				/user/add*/** = perms[user:add] <!-- 添加权限 -->
				/user/delete*/** = perms[user:delete] <!-- 删除权限 -->
				/user/update*/** = perms[user:update] <!-- 修改权限 -->
				/user/changeStatus/** = perms[user:enableOrDisable] <!-- 启用禁用用户 -->
				/user/resetPassword/** = perms[user:resetPwd] <!-- 重制密码 -->

				<!-- 部门权限  -->
				/company/get*/** = perms[company:view] <!-- 查看权限 -->
				/view/company/** = perms[company:view] <!-- html权限控制 -->
				/company/add*/** = perms[company:add] <!-- 添加权限 -->
				/company/delete*/** = perms[company:delete] <!-- 删除权限 -->
				/company/update*/** = perms[company:update] <!-- 修改权限 -->

				<!-- 角色权限  -->
				/role/get*/** = perms[role:view] <!-- 查看权限 -->
				/view/role/** = perms[role:view] <!-- html权限控制 -->
				/role/add*/** = perms[role:add] <!-- 添加权限 -->
				/role/delete*/** = perms[role:delete] <!-- 删除权限 -->
				/role/update*/** = perms[role:update] <!-- 修改权限 -->

				<!-- 权限管理  -->
				/permission/get*/** = perms[permission:view] <!-- 查看权限 -->
				/view/permission/** = perms[permission:view] <!-- html权限控制 -->
				/permission/add*/** = perms[permission:add] <!-- 添加权限 -->
				/permission/delete*/** = perms[permission:delete] <!-- 删除权限 -->
				/permission/update*/** = perms[permission:update] <!-- 修改权限 -->

				/**=rest[authc]<!-- 拦截所有get、post请求 -->
			</value>
			<!-- /**=rest[authc]  验证所有后台如get、post请求 -->
		</property>

	</bean>

  <bean id="logout" class="org.apache.shiro.web.filter.authc.LogoutFilter">
        <property name="redirectUrl" value="/login" />
  </bean>

  <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
	    <property name="realm" ref="monitorRealm" />
	    <!-- 需要使用cache的话加上这句
	    <property name="cacheManager" ref="shiroEhcacheManager" />
	     -->
  </bean>

  <!-- depends-on 表示在实例化该对象之前先实例化 depends-on中的对象 -->
  <bean id="monitorRealm" class="com.hbs.dipper.interceptor.MonitorRealm" />

  <!-- 启用spring注解方式拦截shiro权限 -->
  <bean
    class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
    <property name="securityManager" ref="securityManager" />
  </bean>

  <!-- 自定义角色过滤器 支持多个角色可以访问同一个资源 eg:/home.jsp = authc,roleOR[admin,user]  用户有admin或者user角色 就可以访问-->
  <!-- <bean id="roleOR" class="com.yale.app.security.OneRoleAuthorizationFilter"/> -->

   <!-- srping注解配置 Post processor that automatically invokes init() and destroy() methods -->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<!-- 启用shiro为spring配置的bean注释,只运行在lifecycleBeanProcessor之后  -->
    <bean id="annotationProxy" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
    depends-on="lifecycleBeanPostProcessor">
		<property name="proxyTargetClass" value="true" />
    </bean>

     <!-- 用户授权信息Cache, 采用EhCache,需要的话就配置上此信息
  <bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
    <property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml" />
  </bean>
  -->

  	<!-- spring对ehcache的缓存工厂支持 -->
	<!-- <bean id="ehCacheManagerFactory"
		class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
		<property name="configLocation" value="classpath:ehcache.xml" />
	</bean> -->

</beans>

shiro加载权限具体实现类

package com.hbs.dipper.interceptor;

import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
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.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Component;

import com.hbs.dipper.system.model.Permission;
import com.hbs.dipper.system.model.Role;
import com.hbs.dipper.system.model.User;
import com.hbs.dipper.system.service.PermissionService;
import com.hbs.dipper.system.service.RoleService;
import com.hbs.dipper.system.service.UserService;
import com.hbs.dipper.util.SpringContextUtil;
@Component
public class MonitorRealm extends AuthorizingRealm {

	//由于shiro是在其他service之前加载,所以必须在运行时加载
	UserService userService;
	RoleService roleService;
	PermissionService permissionService;
	private Logger logger = Logger.getLogger(MonitorRealm.class);

	/**
     * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用.
     * 将权限查出来
     */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals) {
		logger.debug("get permissions================================>");
		Subject currentUser =SecurityUtils.getSubject();
		Session session = currentUser.getSession();
        User user = (User) session.getAttribute("user");
		 if( user != null ) {
           SimpleAuthorizationInfo info = (SimpleAuthorizationInfo) session.getAttribute("info");
           if(info==null){
        	   info = new SimpleAuthorizationInfo();
	           if(user.getUserId().equals(1)){//超级管理员,查出所有权限
	        	   info.addRole("admin");
	        	   List<Permission> permissions = permissionService.getList(null);
	        	   addPermission(info,permissions);
	           }else{//从数据库查出权限并添加
		           List<Role> roles = roleService.getRoleByUser(user.getUserId());
		           for (Role role : roles) {
		        	   info.addRole(role.getRoleName());
		        	   List<Permission> permissions = permissionService.getPermissionByRole(role.getRoleId());
		        	   for (Permission permission : permissions) {
		         		   info.addStringPermission(permission.getPermissionCode());
		        	   }
		           }
	           }
	           session.setAttribute("info", info);//缓存到session中
           }
           return info;
        } else {
        	throw new AuthorizationException("login user is null!");
        }
	}

	/**
	* @Title: addPermission
	* @Description: TODO(迭代添加权限)
	* @param @param info
	* @param @param list    参数
	* @return void    返回类型
	* @throws
	 */
	public void addPermission(SimpleAuthorizationInfo info,List<Permission> list){
		for (Permission permission : list) {
 		   info.addStringPermission(permission.getPermissionCode());
 		   if(permission.getChildren()!=null&&permission.getChildren().size()>0)
 			  addPermission(info,permission.getChildren());
 	   }
	}

	/**
     * 认证回调函数,登录时调用.
     * 经测试登陆时会调用两次。。。
     */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken authcToken) throws AuthenticationException {
		bind();
		logger.debug("login=================================>");
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
        String  password = String.valueOf(token.getPassword());
        //调用操作数据库的方法查询user信息
        User user = userService.getByLoginName(token.getUsername()) ;
        if( user != null ) {
            if(password.equals(user.getPassword())){
            	return new SimpleAuthenticationInfo(user.getUserId(), user.getPassword(), getName());
            }else{
                return null;
            }
        } else {
            return null;
        }
	}

	private void bind(){
		if(userService==null)
			userService = (UserService) SpringContextUtil.getBean("userService");
		if(roleService==null)
			roleService = (RoleService) SpringContextUtil.getBean("roleService");
		if(permissionService==null)
			permissionService = (PermissionService) SpringContextUtil.getBean("permissionService");
	}

	public void clearCachedAuthorizationInfo(String principal) {
		SimplePrincipalCollection principals =
			new SimplePrincipalCollection(principal, getName());
		clearCachedAuthorizationInfo(principals);
	}
}

尚未解决的问题: 无法在shiro的Realm中使用注解 ,报空异常,初步判断是在spring加载其他bean之前执行了

时间: 2024-08-19 02:05:57

使用Shiro 集合Spring来实现权限控制的相关文章

shiro 实现登录认证和权限控制

1 添加依赖jar包 <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.3.2</version></dependency><dependency> <groupId>org.apache.shiro</groupId> <art

shiro进行权限控制的四种方式

```我们使用shiro进行权限控制 有以下几种方式 1. URL拦截权限控制:基于filter过滤器实现 我们在spring配置文件中配置shiroFilter时配置 <!--指定URL级别拦截策略 --> <property name="filterChainDefinitions"> <value> /css/ = anon /js/ = anon /images/ = anon /validatecode.jsp = anon /login.

Spring Security 动态url权限控制(三)

一.前言 本篇文章将讲述Spring Security 动态分配url权限,未登录权限控制,登录过后根据登录用户角色授予访问url权限 基本环境 spring-boot 2.1.8 mybatis-plus 2.2.0 mysql 数据库 maven项目 Spring Security入门学习可参考之前文章: SpringBoot集成Spring Security入门体验(一)https://blog.csdn.net/qq_38225558/article/details/101754743

springmvc+spring+mybatis+maven项目集成shiro进行用户权限控制【转】

项目结构: 1.maven项目的pom中引入shiro所需的jar包依赖关系 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <dependency>     <groupid>javax.servlet</groupid>     javax.servlet-api</artifactid>     <version>3.0.1</version>

Spring boot后台搭建二为Shiro权限控制添加Redis缓存

在添加权限控制后,添加方法 查看 当用户访问”获取用户信息”.”新增用户”和”删除用户”的时,后台输出打印如下信息 , Druid数据源SQL监控 为了避免频繁访问数据库获取权限信息,在Shiro中加入缓存 缓存有基于Redis和Ehcache的,本文只介绍基于Redis的 1.Shiro集成Redis的引入依赖 <dependency> <groupId>org.crazycake</groupId> <artifactId>shiro-redis<

shiro权限控制配置

shiro配置流程 web.xml中配置shiro的filter spring中配置shiro的过滤器工厂,指定对不同地址权限控制 , 传入安全管理器 配置安全管理器,传入realm,realm中定义具体授权和认证的流程 配置自定义凭证匹配器,指定token和info的匹配方式. 权限访问的配置 定义所有的权限的String集合 在自定义realm中重写doGetAuthoriaztionInfo(),创建所有权限的String集合, 创建SimpleAuthorizationInfo的对象,调

Shiro权限控制框架入门1:Shiro的认证流程以及基本概念介绍

前言:我在最开始学习Shiro这个框架时,在网上搜索到的一个介绍比较全面的教程是:<跟我学Shiro>系列教程.但是在我看了他写的前几篇文章后,我发现虽然他在这个系列教程中把shiro的一些特性介绍地非常全面详细,但是整个教程的叙述方式还是有很大缺陷的.文章与文章之间并没有很好地串联起来,每篇文章介绍的东西都过于分散了,如果是对shiro完全不了解的新手来看的话完全是一场噩梦.就像一个网友评价的这样: 看了看这个教程,看完之后都想放弃shiro了,完全看不懂,后来百度了很多别的资料才理解了sh

shiro权限控制

1.1  简介 Apache Shiro是Java的一个安全框架.目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring Security,可能没有Spring Security做的功能强大,但是在实际工作时可能并不需要那么复杂的东西,所以使用小而简单的Shiro就足够了.对于它俩到底哪个好,这个不必纠结,能更简单的解决项目问题就好了. 本教程只介绍基本的Shiro使用,不会过多分析源码等,重在使用. Shiro可以非常容易的开发出足够好的应用,其不仅可以用在JavaS

shiro框架的四中权限控制方式

一.在自定义的realm中进行权限控制 在applicationContext.xml文件中添加  /areaAction_pageQuery.action = perms["area"] <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!-- 注入shiro框架核心对象,安全管理器 --> <pr