shiro安全框架

概念

Shiro是apache基金会旗下的一款安全框架,其中包括登陆认证/权限控制/session管理/加密处理.这四大模块。

shiro安全框架四大组件

  1. Authentication登录认证

    当用户访问时必须登录。这时,shiro会进行验证通过。

  2. Authorization权限认证

    不同用户登录系统时,由于权限不同,所看到的功能不同。

  3. SessionMangement

    由shiro框架对javax.servlet中的session进行了再次包装。

  4. Cryptography加密处理

    包含了加密算法(内部匹配规则)与工具类。

Shiro内部流程调用关系

shiro内部流程调用关系

  • ApplicationCode
    任何形式的请求(线程/机器/用户请求)
  • Subject
    是shiro安全中心对外暴露的唯一入口。当一个请求到达时都会经过Subject才能到达shiro内部进行校验,所以每个请求都相当于一个”user”来进行处理,
  • ShiroSecurityManager
    核心部分。Shiro内部有自己的校验规则,不需要程序员干预。
  • Realm
    通过Realm查询用户的真实信息,然后返回给安全中心内部,进行自动校验。但是程序员需要准备Realm原材料.

搭建步骤

spring整合shiro框架

  1. 导入依赖的jar包
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.8.3</version>
</dependency>
  1. 编辑配置文件–spring整合shiro框架
  • applicationContext-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:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
				         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
				         http://www.springframework.org/schema/context
				         http://www.springframework.org/schema/context/spring-context-3.0.xsd
				         http://www.springframework.org/schema/tx
				         http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
				         http://www.springframework.org/schema/aop 
				         http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
	 
	 <!-- 将shiro的四大组件的生命周期 交给 spring框架管理 -->
	 <bean id="lifeCycleBeanProcessor" 
	 class="org.apache.shiro.spring.LifecycleBeanPostProcessor"></bean>
	 
	 <!-- 创建shiro的代理对象 
	 	 代理:在完成本职工作的同时,添加额外的操作
	 	 额外的操作:原材料realm的准备
	 	           加密模块的匹配规则(MD5算法)
	              权限的查询:根据当前登录的用户去查询数据库的权限模块
	  	 动态代理的两种模式:jdk的动态代理/ cglib的动态代理
	  -->
	 <bean 
	 class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
	 depends-on="lifeCycleBeanProcessor">
	 	<property name="proxyTargetClass" value="true"></property>
	 </bean>
	
	 <!-- 强制制定使用 cglib的代理模式
	      proxy-target-class="true"
	  -->
	 <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
  	
  	
	 <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
	 	<!--引用 程序员编写的realm的原材料  -->
	 	<property name="realm" ref="AuthRealm"></property>
	 </bean>
	 <!-- 自己编写的处理原材料的程序 -->
	 <bean id="AuthRealm" class="cn.tarena.ht.shiro.AuthRealm">
		 <!-- 自定义的加密算法 :引用bean标签
		 	  name="credentialsMatch" 与 
		 	  authCredential类的方法名对应
		  -->
		 <property name="credentialsMatcher" ref="authCredential"></property>
	 </bean>
	 <!-- 自定义的加密算法 -->
	 <bean id="authCredential" 
	 class="cn.tarena.ht.shiro.AuthCredential"></bean>
	 
	 <!-- 权限认证交给 shiro的安全中心管理   -->
	 <bean  class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
	 	<property name="securityManager" 
	 	ref="securityManager"></property>
	 </bean>
	 
	<!-- shiro的过滤器
		所有的请求 都需要经过过滤器
		
	 -->
	 <bean id="shiroFilter"  class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
	 	<!-- 引入shiro的安全管理中心 -->
	 	<property name="securityManager" ref="securityManager"></property>
	    <!-- 指定登录的地址  当用户没有登录时,默认跳转的页面 -->
	 	<property name="loginUrl" value="/index.jsp"></property>
	    <!-- 过滤链:values标签中配置的所有请求 -->
	 	<property name="filterChainDefinitions">
	 	<value>
	 		<!-- 
	 		     请求:  
	 		     静态的配置文件  放行 不拦截
		             动态的客户端的请求  拦截大部分请求,但是登录请求要拦截吗?
		    -->
	 	    <!-- 
	 			添加过滤信息
	 			1.anon 表示放行
	 			2.authc 表示拦截
	 		 -->
	 		/tologin.action = anon
	 		/logout.action = anon
	 		/login.action = anon
	 		/staticfile/** = anon
	 		<!-- /**拦截所有的请求和静态资源文件 -->
	 		/** = authc
	 	</value>
	 	</property>
	 </bean>
</beans> 
  • web容器管理shiro过滤链–web.xml
<!-- shiro安全框架的过滤器交给web容器
		filter-name必须要和配置文件中bean的id一致
	 -->
	<filter>
  		<filter-name>shiroFilter</filter-name>
  		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  			<init-param>
  				<!--配置过滤器的一个生命周期  -->
  				<param-name>targetFilterLifecycle</param-name>
  				<param-value>true</param-value>
  			</init-param>
   </filter>
  
  <filter-mapping>
  	<filter-name>shiroFilter</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>

3.自定义Realm
Realm

  • 自定义过滤器(在pom.xml中已配置)
    在这里插入图片描述
  • 将过滤器交给web容器进行管理(在web.xml中已添加过滤器)
    在这里插入图片描述

Shiro安全认证步骤

  1. Shiro安全管理进行登录认证(Subject:在LoginController类中)
@RequestMapping(value="/login")
	public String toLogin(String username,String password,Model model){
		//验证用户名密码是否为空
		if(StringUtils.isEmpty(username)||StringUtils.isEmpty(password)){
			model.addAttribute("errorInfo", "用户名或密码不能为空");
			return "/sysadmin/login/login";
		}
		
		//验证用户名密码是否正确--使用shiro提供的subject类
		//这个subject时所有请求对应的统一对象
		Subject subject = SecurityUtils.getSubject();//有安全管理中心创建对象
		
		//使用令牌进行登录--AuthenticationToken
		UsernamePasswordToken token = new UsernamePasswordToken(username,password);
		//如果令牌错误不能正常登录
		try {
			subject.login(token);
			//获取真实的对象
			User user = (User) subject.getPrincipal();
			//放入shiro提供的session中
			subject.getSession().setAttribute("sessionUser", user);
			return "redirect:/home";
		} catch (Exception e) {//令牌出现错误,打印异常信息,并提示登录错误,返回登录页面
			e.printStackTrace();
			model.addAttribute("errorInfo", "用户名或密码不正确");
			return "/sysadmin/login/login";
		}

	}
  1. 登录认证—自定义的Realm
public class AuthRealm extends AuthorizingRealm{
	
	@Autowired
	private UserService userService;

	//权限认证方法:查询当前用户对应的模块权限
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
		// TODO Auto-generated method stub
		return null;
	}
	
	//用户认证:1.拿到用户名密码   2.用户名密码进行加密
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		//获取用户名和密码的令牌
		UsernamePasswordToken loginToken = (UsernamePasswordToken) token;
		
		// 通过令牌对象获取 前端页面输入的 用户名信息
		String username = loginToken.getUsername();
		
		// 根据username,去数据库中查询当前用户是否存在
		// 程序员手动准备的原材料信息
		/* sql语句:查询用户的信息的同时获取 部门信息
		 * mapper层
		 * service层
		 */
		User user = userService.findUserByUsername(username);
		
		//返回值类型为:AuthenticationInfo
		// 结果:只是根据用户名去查询了 数据库
		/* principal : 表示真实的用户 user
		 * credentials : 表示 user对象的 密码
		 * realmName : 原材料的类名 string字符串 this.getName()
		 */
		AuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());
		return info;
	}

}
  1. shiro内部密码规则校验
//shiro安全中心根据密码,进行内部规则校验
public class AuthCredential extends SimpleCredentialsMatcher{
	
	@Override
	public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
		//获取用户名密码的令牌
		UsernamePasswordToken loginToken = (UsernamePasswordToken) token;
		
		//获取用户名密码
		String username = loginToken.getUsername();
		String password = String.valueOf(loginToken.getPassword());
		
		//进行MD5加密
		String md5passsword =  MD5Password.getMd5HashPassword(username, password);
		loginToken.setPassword(password.toCharArray());
		
		//调用父类的内部校验规则:令牌和登录认证的原材料info信息
		return super.doCredentialsMatch(token, info);
	}

}

在这里插入图片描述

  1. 权限控制
  • 在jsp页面中引入shiro标签库
<%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro"%>
  • 管理相应的模块标题
<shiro:hasPermission name="部门管理">
	<li><a href="${ctx}/sysadmin/dept/list" onclick="linkHighlighted(this)" target="main" id="aa_1">部门管理</a></li>
</shiro:hasPermission>
  • 自定义的Realm中进行权限认证
@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
		Subject subject = SecurityUtils.getSubject();
		User user = (User) subject.getPrincipal();
		String userId  = user.getUserId();
		//根据userId查询模块信息
		List<String> pList = userService.findModuleByUserId(userId);
		//创建权限控制对象
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		info.addStringPermissions(pList);
		return info;
	}
  • 根据userId查询模块信息–在userMapper.xml中编写sql语句
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值