cadre de sécurité shiro

Cadre de sécurité commun

  1. apache shhiro
    peut être appliqué à n'importe quel système d'application et ne dépend pas de la structure du ressort.
    Simple et facile à démarrer.
    Généralement utilisé dans les applications SSM traditionnelles.
  2. Springsecurity
    est l'un des modules du cadre de ressort et doit dépendre du système de ressort.
    Plus puissant et complexe,
    généralement utilisé pour le développement distribué de microservices springboot + springcloud

L'objectif du cadre de sécurité

  1. Connexion utilisateur d'authentification utilisateur
  2. Contrôle de l'autorité de gestion de l'autorité de ressources (rôle)

L'architecture du cadre shiro

Insérez la description de l'image ici
Description:

  1. Gestionnaire de sécurité Security Manager
  2. Vérification de l'utilisateur Authenticator Authenticator (connexion)
  3. Gestion de l'autorité d' autorisation (contrôle)
  4. Gestionnaire de session Le gestionnaire de session gère la session et gère en outre la session
  5. Session DAO conserve les données de session
  6. Cache Manager est utilisé pour la gestion du cache des données de menu
  7. La cryptographie fournit des algorithmes de cryptage pour les mots de passe, par exemple MD5
  8. Realms signifie "royaumes". Encapsule principalement les composants de la logique métier d'authentification et d'autorisation. (Domaine système ou domaine personnalisé)
  9. Sujet de vérification du sujet, individu, application, application

Le processus de certification du cadre shiro

Insérez la description de l'image ici

Authentification des utilisateurs Shiro

Étapes de mise en œuvre du programme d'entrée

  • Importer la bibliothèque de pots de Shiro
    Insérez la description de l'image ici
  • Ajouter le fichier de configuration shiro * .ini
    syntaxe:
    - [users] définit la liste des utilisateurs
    - [main] la "racine" du conteneur correspondant au fichier de configuration ini, qui est équivalent à applicationContext.xml
  • Code de test
	@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());
		
	}

Résultat:
Erreur de compte: org.apache.shiro.authc.UnknownAccountException
Erreur de mot de passe: org.apache.shiro.authc.IncorrectCredentialsException

  • Royaume personnalisé
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;
	}
}

Gestion des permissions de Shiro

1. L'ID d'autorisation requis par l'URI de la demande doit être spécifié dans le fichier de configuration

	<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. Autoriser les utilisateurs dans le royaume personnalisé

	//权限授予
	@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;
	}

Application intégrée de shiro et ssm

La configuration de base est la suivante:

  • 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>
  • Configuration du fichier printemps applicationContext.xml
	<!-- 开启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>

Esquisse du processus d'authentification des utilisateurs:
Insérez la description de l'image ici

Je suppose que tu aimes

Origine blog.csdn.net/weixin_45879810/article/details/108770571
conseillé
Classement