关于shiro权限控制

shiro是Apache 推出的一个权限管理框架。

它主要有三个核心组件:

    Subject :当前操作用户(人、第三方进程等)

    SecurityManager :管理内部组件、提供各种安全管理服务

    Realms shiro和系统安全数据之间的“桥梁”、“连接者”,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。


 shiro整合spring

配置:

1.依赖

2.Web.xml

3.applicationContext.xml

配置如下图:



spring整合shiro实例:

1.application.xml(spring)文件的配置

<?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:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
		http://www.springframework.org/schema/data/jpa 
		http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
	
	<!-- 配置Shiro核心Filter  --> 
	<bean id="shiroFilter" 
		class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<!-- 安全管理器 -->
		<property name="securityManager" ref="securityManager" />
		<!-- 未认证,跳转到哪个页面  -->
		<property name="loginUrl" value="/login.html" />
		<!-- 登录页面页面 -->
		<property name="successUrl" value="/index.html" />
		<!-- 认证后,没有权限跳转页面 -->
		<property name="unauthorizedUrl" value="/unauthorized.html" />
		<!-- shiro URL控制过滤器规则 
			anon  未认证可以访问,直接放行
			authc  认证后可以访问
			perms 需要特定权限才能访问 
			roles 需要特定角色才能访问 
			user 需要特定用户才能访问 
			port  需要特定端口才能访问
			reset  根据指定 HTTP 请求访问才能访问 -->
		<property name="filterChainDefinitions">
			<value>
				/login.html* = anon
				/user_login.action* = anon 
				/validatecode.jsp* = anon
				/css/** = anon
				/js/** = anon
				/images/** = anon
				/services/** = anon 
				<!-- securityManager查询数据库后根据结果做出操作 -->
				<!-- 特定的权限才能操作 -->
				/pages/base/courier.html* = perms[courier:list]
				<!-- 特定的角色才能访问 -->
				/pages/base/area.html* = roles[base]
				/** = authc
			</value>
		</property>
	</bean>
	
	<!-- 安全管理器  -->
	<bean id="securityManager" 
		class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
			<!-- 注入自定义的realm -->		
			<property name="realm" ref="bosRealm" />
			<!-- <property name="cacheManager" ref="shiroCacheManager" /> -->
	</bean>
	
	<!-- 配置Realm:范围、领域 -->
	<!-- <bean id="bosRealm" class="cn.boom.bos.realm.BosRealm">
		缓存区的名字 就是 ehcache.xml 自定义 cache的name
		<property name="authorizationCacheName" value="bos" />
	</bean> -->
	<bean id="lifecycleBeanPostProcessor" 
			class="org.apache.shiro.spring.LifecycleBeanPostProcessor"></bean>
	
	<!-- 开启shiro注解模式  -->
	<bean
		class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
		depends-on="lifecycleBeanPostProcessor" >
		<!-- 设置为使用cglib方式的动态代理 -->
		<property name="proxyTargetClass" value="true" />
	</bean>
		
	<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
		 <property name="securityManager" ref="securityManager"/>
	</bean>
	
</beans>

自定义的Realm:

package cn.boom.bos.realm;

import java.util.List;

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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.boom.bos.domain.system.Permission;
import cn.boom.bos.domain.system.Role;
import cn.boom.bos.domain.system.User;
import cn.boom.bos.service.system.PermissionService;
import cn.boom.bos.service.system.RoleService;
import cn.boom.bos.service.system.UserService;

/**
 * 自定义的realm,继承Realm接口,实际开发中只需要继承AuthorizingRealm  
 * @author peng   2018年3月26日
 *
 */
//在配置文件中配置了
@Service("bosRealm")
public class BosRealm extends AuthorizingRealm{

	@Autowired
	private UserService userService;
	@Autowired
	private RoleService roleService;
	@Autowired
	private PermissionService permissionService;
	
	/*
	 * 授权
	 * @see org.apache.shiro.realm.AuthorizingRealm#doGetAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection)
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {
		System.out.println("测试:shiro的授权管理");
		
		//注意应为org.apache.shiro.authz.SimpleAuthorizationInfo;
		//simpleAuthorizationInfo : 简单的授权信息
		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
		
		/*根据当前登陆的用户获得其角色和权限*/
		Subject subject = SecurityUtils.getSubject();
		User user = (User) subject.getPrincipal();
		
		//调用业务层查询其角色
		List<Role> roles = roleService.findByUser(user);
		for (Role role : roles) {
			String keyword = role.getKeyword();
			simpleAuthorizationInfo.addRole(keyword);
		}
		
		//调用业务层,查询权限
		List<Permission> permissions = permissionService.findByUser(user);
		for (Permission permission : permissions) {
			String keyword = permission.getKeyword();
			simpleAuthorizationInfo.addStringPermission(keyword);
		}
		
		return simpleAuthorizationInfo;
	}

	
	/*
	 * 认证
	 * @see org.apache.shiro.realm.AuthenticatingRealm#doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken)
	 * 返回的类型为	new SimpleAuthenticationInfo(principal, credentials, realmName)
	 * 		参数一: 期望登录后,保存在Subject中信息
	 * 		参数二: 如果返回为null 说明用户不存在,报用户名
	 * 		参数三 :realm名称
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken token) throws AuthenticationException {

		System.out.println("测试:shiro的认证管理");
		
		UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
		
		User user 
			= userService.findByUsername(usernamePasswordToken.getUsername());
		System.out.println("测试   传过来的密码为:"+usernamePasswordToken.getPassword());
		if (user == null) {
			
			return null;
		} else {
			// 当返回用户密码时,securityManager安全管理器,自动比较返回密码和用户输入密码是否一致
			// 如果密码一致 登录成功, 如果密码不一致 报密码错误异常
			System.out.println("测试  返回的密码为"+user.getPassword());
			return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
		}
	}


}

action示例:

package cn.boom.bos.web.action.system;

/**
 * 
 * @author peng   2018年3月26日
 *
 */
@Controller
@Scope("prototype")
@Namespace("/")
@ParentPackage("json-default")
public class UserAction extends BaseAction<User>{
	
	/*
	 * 用户登录,基于权限控制
	 */
	@Action(value="user_login",results={
			@Result(name="login",type="redirect",location="login.html"),
			@Result(name="success",type="redirect",location="index.html")
	})
	public String login(){
		//基于shiro实现权限控制
		Subject subject = SecurityUtils.getSubject();
		
		//用户的用户名及密码信息
		AuthenticationToken token = 
				new UsernamePasswordToken(model.getUsername(), model.getPassword());
		
		try {
			//登录
			subject.login(token);    //执行Realm中的认证方法
			System.out.println("测试:登录成功");
			return SUCCESS;
		} catch (AuthenticationException e) {
			System.err.println("登录过程发生错误");
			e.printStackTrace();
		}
		
		return "login";
	}
	
	/*
	 * 用户注销
	 */
	@Action(value="user_logout",results={
			@Result(name="success",type="redirect",location="login.html")
	})
	public String logout(){
		//查询到当前的用户 , 并自动操作session完成注销
		Subject subject = SecurityUtils.getSubject();
		subject.logout();
		
		return SUCCESS;
	}
	
}










猜你喜欢

转载自blog.csdn.net/HELLOMRP/article/details/79736446
今日推荐