shiro安全性框架

常用的安全性框架

  1. apache shhiro
    可以应用于任何的应用系统中,不依赖于spring框架。
    简单,入门容易。
    一般用于传统的SSM的应用比较多。
  2. springsecurity
    是spring框架的其中的模块,必须依赖于spring体系。
    功能更强大,较复杂
    一般用于springboot+springcloud微服务分布式开发较多

安全性框架的解决目标

  1. 用户认证 用户登录
  2. 资源的权限管理 权限(角色)的控制

shiro 框架的架构

在这里插入图片描述
说明:

  1. Security Manager 安全管理器
  2. Authenticator 认证器 用户的验证(登录)
  3. Authorizer 授权器 权限管理(控制)
  4. Session Manager 会话管理器 托管session,进一步对session进行管理
  5. Session DAO 维护session的数据
  6. Cache Manager 缓存管理器 用于菜单数据的缓存管理
  7. Cryptography 提供密码的加密算法 例如, MD5
  8. Realms "领域"的意思。主要封装验证和授权的业务逻辑的组件。( 系统的realm或 自定义realm)
  9. Subject 验证的主体, 个人、应用、app

shiro框架的认证流程

在这里插入图片描述

shiro的用户认证

入门程序的实现步骤

  • 导入 shiro的jar类库
    在这里插入图片描述
  • 添加shiro的配置文件 *.ini
    语法:
    – [users] 定义用户列表
    – [main] ini配置文件对应的容器的“根”,相当于applicationContext.xml中
  • 测试代码
	@Test  //入门认证: 使用默认的realm
	public void testLoginAndLogout() {
    
    
		
		Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-first.ini");
		SecurityManager securityManger = factory.getInstance();
		//构建securityManger环境
		SecurityUtils.setSecurityManager(securityManger);
		//获取认证的主体
		Subject subject = SecurityUtils.getSubject();
		
		//封装认证的令牌
		UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "111111");
		try {
    
    
			subject.login(token);   // 使用默认的系统的realm做用户认证。
		} catch (AuthenticationException e) {
    
    
			e.printStackTrace();
		}
		
		System.out.println("是否认证成功:" + subject.isAuthenticated());
		
		subject.logout();
		
		System.out.println("是否认证成功:" + subject.isAuthenticated());
		
	}

结果:
帐号错误: org.apache.shiro.authc.UnknownAccountException
密码错误:org.apache.shiro.authc.IncorrectCredentialsException

  • 自定义realm
package com.gec.shiro.realm;

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.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

//需继承AuthorizingRealm
public class CustomRealm extends AuthorizingRealm {
    
    
	//执行认证
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    
    
		//先获取用户的帐号
		String username = (String) token.getPrincipal();
		
		//伪代码
//		User loginUser = userService.findUserByusername(username);
//		if(loginUser == null) {
    
    
//			return null;   //报异常:UnknownAccountException
//		}
//		String password_db = loginUser.getPassword();
		
		String username_db = "zhangsan";
		if(!username.equals(username_db)){
    
    
			return null;
		}
		String password_db = "111111";
		
		SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password_db, "CustomRealm");
		return info;
	}
	
	//执行授权
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
    
    
		// TODO Auto-generated method stub
		return null;
	}
}

shiro的权限管理

1.需在配置文件中指定请求 URI 所需的权限标识

	<property name="filterChainDefinitions">
		<value>
			<!-- 所有的静态资源要匿名访问 -->
				/bootstrap/**=anon
			    /css/**=anon
			    /js/**=anon
			    /static/**=anon
			    /images/**=anon
			    /styles/**=anon
			    <!-- 授权过滤器  , 建议使用注解授权或在jsp页面使用标签-->
			    /apply_baoxiao.jsp=perms[baoxiao:apply]
			    /myBaoxiaoBill=perms[baoxiao:billquery]
			    /myTaskList=perms[baoxiao:tasklist]
			    /add_process.jsp=perms[baoxiao:publish]
			    /processDefinitionList=perms[baoxiao:processlist]
			    /findUserList=perms[user:query]
			    /toAddRole=perms[user:create]
			    /findRoles=perms[baoxiao:rolelist]
			  	 
			  	 
			    /first=user
			    <!-- 退出系统 -->
			    /logout=logout
				/**=authc
				
			</value>
		</property>				

2.在自定义 Realm 中给用户授权

	//权限授予
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
    
    	
		//从主体中获取用户信息
		ActiveUser activeUser = (ActiveUser) principal.getPrimaryPrincipal();
		List<SysPermission> permissions = null;
		try {
    
    
			//从数据库中查找用户的权限信息
			permissions = sysService.findPermissionListByUserId(activeUser.getUsercode());
		} catch (Exception e) {
    
    
			e.printStackTrace();
		}
		List<String> percodes = new ArrayList<>();
		for (SysPermission sysPermission : permissions) {
    
    
			//获取权限信息里的权限标识并加入列表
			percodes.add(sysPermission.getPercode());
		}
		//把权限列表授权给用户
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		info.addStringPermissions(percodes);
		return info;
	}

shiro和ssm的整合应用

基础配置如下:

  • web.xml
	<!-- shiro的filter -->
	<!-- shiro过虑器,DelegatingFilterProxy通过代理模式将spring容器中的bean和filter关联起来 -->
	<filter>
		<filter-name>shiroFilter</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
		<!-- 设置true由servlet容器控制filter的生命周期 -->
		<init-param>
			<param-name>targetFilterLifecycle</param-name>
			<param-value>true</param-value>
		</init-param>
		<!-- 设置spring容器filter的bean id,如果不设置则找与filter-name一致的bean -->
		<init-param>
			<param-name>targetBeanName</param-name>
			<param-value>shiroFilter</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>shiroFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
  • applicationContext.xml spring文件的配置
	<!-- 开启aop,对类代理 -->
	<aop:config proxy-target-class="true"></aop:config>
	<!-- 开启shiro注解支持 -->
	<bean  class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
		<property name="securityManager" ref="securityManager" />
	</bean>

	<!-- web.xml中shiro的filter对应的bean -->
	<!-- Shiro 的Web过滤器 -->
	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<property name="securityManager" ref="securityManager" />
		<!-- loginUrl认证提交地址,如果没有认证将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 -->
		<property name="loginUrl" value="/login.action" />
		<!-- 认证成功统一跳转到first.action,建议不配置,shiro认证成功自动到上一个请求路径 -->
		<property name="successUrl" value="/first.action" />
		<!-- 通过unauthorizedUrl指定没有权限操作时跳转页面 -->
		<property name="unauthorizedUrl" value="/refuse.jsp" />		
		<!-- 自定义filter配置 -->
		<property name="filters">
			<map>
				<!-- 将自定义 的FormAuthenticationFilter注入shiroFilter中-->
				<entry key="authc" value-ref="formAuthenticationFilter" />
			</map>
		</property>
		<!-- 过虑器链定义,从上向下顺序执行,一般将/**放在最下边  -->
		<property name="filterChainDefinitions">
			<value>
			    <!-- 所有的静态资源要匿名访问 -->
			    /js/**=anon
			    /images/**=anon
			    /styles/**=anon
			    /validatecode.jsp=anon
			    
			    /items/queryItem.action=perms[item:query]
			    /items/editItems.action=perms[item:update]
			    
			    <!-- 退出系统 -->
			    /logout.action=logout
			    
				/**=authc
				
			</value>
		</property>
	</bean>

	<!-- securityManager安全管理器 -->
	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
		<property name="realm" ref="customRealm" />
		<property name="cacheManager" ref="cacheManager"/>
	</bean>

	<!-- realm -->
	<bean id="customRealm" class="cn.items.ssm.shiro.CustomRealm">
		<property name="credentialsMatcher" ref="credentialsMatcher" />
	</bean>
	
	<!-- 凭证匹配器 -->
	<bean id="credentialsMatcher"
		class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
		<property name="hashAlgorithmName" value="md5" />
		<property name="hashIterations" value="2" />
	</bean>
	
     <!-- 自定义form认证过虑器 -->
	<!-- 基于Form表单的身份验证过滤器,不配置将也会注册此过虑器,表单中的用户账号、密码及loginurl将采用默认值,建议配置 -->
	<bean id="formAuthenticationFilter" class="cn.items.ssm.shiro.CustomFormAuthenticationFilter">
		<!-- 表单中账号的input名称 -->
		<property name="usernameParam" value="username" />
		<!-- 表单中密码的input名称 -->
		<property name="passwordParam" value="password" />
   </bean>
    
    <!-- 缓存管理器 -->
	<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
    	<property name="cacheManagerConfigFile" value="classpath:shiro-ehcache.xml"/>
    </bean>

用户认证的流程草图:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45879810/article/details/108770571
今日推荐