Shiro integra la Web

El proceso web de Shiro

imagen.png

Shiro integra SSM

  • Preparar la configuración de SSM
  • Prepara las cinco tablas clásicas (ver uso básico de Shiro ) y completa la prueba.
  • Prepara la configuración de Shiro.
    • filtro central

      <!--    配置Shiro整合web的过滤器-->
      <filter>
          <!--        默认情况下,请求到达这个过滤器,会去Spring容器中名字为filter-name的实例去处理-->
          <filter-name>shiroFilter</filter-name>
          <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
      </filter>
      <filter-mapping>
          <filter-name>shiroFilter</filter-name>
          <url-pattern>/*</url-pattern>
      </filter-mapping>
      
    • Preparar la instancia de shiroFilter

      <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
      	.....
      </bean>
      
    • Inyectar SecurityManager, ruta de la página de inicio de sesión, cadena de filtros

      <!--    构建realm-->
      <bean id="realm" class="com.xxx.realm.ShiroRealm" />
      
      <!--    构建securityManager-->
      <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
          <property name="realm" ref="realm"/>
      </bean>
      
      <!--    构建ShiroFilter实例-->
      <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
          <property name="securityManager" ref="securityManager"/>
          <property name="loginUrl" value="/login.html" />
          <property name="filterChainDefinitionMap">
              <map>
                  <entry key="/login.html" value="anon" />
                  <entry key="/user/**" value="anon" />
                  <entry key="/**" value="authc" />
              </map>
          </property>
      </bean>
      
    • Modifique la operación de base de datos simulada de ShiroRealm para interactuar con la base de datos (consulte Uso básico de Shiro )

    • Escriba la función de inicio de sesión y pruebe el efecto.

      @PostMapping("/login")
      public String login(String username,String password){
              
              
          // 执行Shiro的认证操作
          //1. 直接基于SecurityUtils获取subject主体,不需要手动的将SecurityManager和SecurityUtils手动整合,Spring已经奥丁
          Subject subject = SecurityUtils.getSubject();
      
          //2. 发起认证
          try {
              
              
              subject.login(new UsernamePasswordToken(username,password));
              return "SUCCESS";
          } catch (UnknownAccountException exception){
              
              
              return "username fail!!!";
          } catch (IncorrectCredentialsException exception){
              
              
              return "password fail!!!";
          } catch (AuthenticationException e) {
              
              
              return "donot know...!!!";
          }
      }
      

Shiro integra SpringBoot

  • Construir proyecto SpringBoot
  • Configurar Shiro para integrar contenido SpringBoot
    @Configuration
    public class ShiroConfig {
          
          
    
        @Bean
        public DefaultWebSecurityManager securityManager(ShiroRealm realm){
          
          
            DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
            securityManager.setRealm(realm);
            return securityManager;
        }
    
        @Bean
        public DefaultShiroFilterChainDefinition shiroFilterChainDefinition(){
          
          
            DefaultShiroFilterChainDefinition shiroFilterChainDefinition = new DefaultShiroFilterChainDefinition();
    
            Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
            filterChainDefinitionMap.put("/login.html","anon");
            filterChainDefinitionMap.put("/user/**","anon");
            filterChainDefinitionMap.put("/**","authc");
    
            shiroFilterChainDefinition.addPathDefinitions(filterChainDefinitionMap);
    
            return shiroFilterChainDefinition;
        }
    }
    

Método de autorización de Shiro

cadena de filtro

public enum DefaultFilter {
    
    
	// ....
    perms(PermissionsAuthorizationFilter.class),
    roles(RolesAuthorizationFilter.class),
	// ....
}
filterChainDefinitionMap.put("/item/select","roles[超级管理员,运营]");
filterChainDefinitionMap.put("/item/delete","perms[item:delete,item:insert]");

imagen.png

Filtros personalizados

  • Implementar filtros personalizados basados ​​en RolesAuthorizationFilter
    /**
     * 在要求的多个角色中,有一个满足要求,就放行
     * @author zjw
     * @description
     */
    public class RolesOrAuthorizationFilter extends AuthorizationFilter {
          
          
        @Override
        protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
          
          
            // 获取主体subject
            Subject subject = getSubject(request, response);
            // 将传入的角色转成数组操作
            String[] rolesArray = (String[]) mappedValue;
            // 健壮性校验
            if (rolesArray == null || rolesArray.length == 0) {
          
          
                return true;
            }
            // 开始校验
            for (String role : rolesArray) {
          
          
                if(subject.hasRole(role)){
          
          
                    return true;
                }
            }
    
            return false;
        }
    }
    
  • Configurar filtros personalizados para Shiro
    @Configuration
    public class ShiroConfig {
          
          
    
        @Bean
        public DefaultWebSecurityManager securityManager(ShiroRealm realm){
          
          
            DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
            securityManager.setRealm(realm);
            return securityManager;
        }
    
        @Bean
        public DefaultShiroFilterChainDefinition shiroFilterChainDefinition(){
          
          
            DefaultShiroFilterChainDefinition shiroFilterChainDefinition = new DefaultShiroFilterChainDefinition();
    
            Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
            filterChainDefinitionMap.put("/login.html","anon");
            filterChainDefinitionMap.put("/user/**","anon");
            filterChainDefinitionMap.put("/item/select","rolesOr[超级管理员,运营]");
            filterChainDefinitionMap.put("/item/delete","perms[item:delete,item:insert]");
            filterChainDefinitionMap.put("/**","authc");
    
            shiroFilterChainDefinition.addPathDefinitions(filterChainDefinitionMap);
    
            return shiroFilterChainDefinition;
        }
    
        @Value("#{ @environment['shiro.loginUrl'] ?: '/login.jsp' }")
        protected String loginUrl;
    
        @Value("#{ @environment['shiro.successUrl'] ?: '/' }")
        protected String successUrl;
    
        @Value("#{ @environment['shiro.unauthorizedUrl'] ?: null }")
        protected String unauthorizedUrl;
    
    
        @Bean
        protected ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager,ShiroFilterChainDefinition shiroFilterChainDefinition) {
          
          
            //1. 构建ShiroFilterFactoryBean工厂
            ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
    
            //2. 设置了大量的路径
            filterFactoryBean.setLoginUrl(loginUrl);
            filterFactoryBean.setSuccessUrl(successUrl);
            filterFactoryBean.setUnauthorizedUrl(unauthorizedUrl);
    
            //3. 设置安全管理器
            filterFactoryBean.setSecurityManager(securityManager);
    
            //4. 设置过滤器链
            filterFactoryBean.setFilterChainDefinitionMap(shiroFilterChainDefinition.getFilterChainMap());
    
            //5. 设置自定义过滤器 , 这里一定要手动的new出来这个自定义过滤器,如果使用Spring管理自定义过滤器,会造成无法获取到Subject
            filterFactoryBean.getFilters().put("rolesOr",new RolesOrAuthorizationFilter());
    
            //6. 返回工厂
            return filterFactoryBean;
        }
    }
    

anotación

  • Cuando se autoriza la anotación, se basa en la representación de la clase Controlador y realiza la verificación de permiso en la solicitud en la mejora previa.

  • Como utilizamos el método de prueba de SpringBoot, podemos agregar anotaciones directamente al método del Controlador.

    @GetMapping("/update")
    @RequiresRoles(value = {
          
          "超级管理员","运营"})
    public String update(){
          
          
        return "item Update!!!";
    }
    
    @GetMapping("/insert")
    @RequiresRoles(value = {
          
          "超级管理员","运营"},logical = Logical.OR)
    public String insert(){
          
          
        return "item Update!!!";
    }
    
    //    @RequiresPermissions(value = "",logical = Logical.AND)
    
  • Las anotaciones entran en vigor de forma predeterminada en Spring Boot porque la compatibilidad con anotaciones se configuró en el ensamblaje automático.

    @Configuration
    @ConditionalOnProperty(name = "shiro.annotations.enabled", matchIfMissing = true)
    public class ShiroAnnotationProcessorAutoConfiguration extends AbstractShiroAnnotationProcessorConfiguration {
          
          
    
        @Bean
        @DependsOn("lifecycleBeanPostProcessor")
        @ConditionalOnMissingBean
        @Override
        public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
          
          
            return super.defaultAdvisorAutoProxyCreator();
        }
    
        @Bean
        @ConditionalOnMissingBean
        @Override
        public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
          
          
            return super.authorizationAttributeSourceAdvisor(securityManager);
        }
    }
    
  • El formulario de anotación no puede ubicar la información de la página de error en 401.html porque la ruta configurada solo es válida para la cadena de filtros y la anotación no es válida. Para lograr el efecto de mensajes amigables, puede configurar controladores de excepciones, @RestControllerAdvice, @ControllerAdvice

Acuérdate de mí

Recuerde que después de activarlo, puedo usar filtros de usuario para interceptar algunas páginas con un nivel de seguridad relativamente más bajo. Siempre que haya iniciado sesión, puedo acceder a ellas sin volver a iniciar sesión.

Preparar dos interfaces.

    @GetMapping("/rememberMe")
    public String rememberMe(){
    
    
        return "rememberMe!!!";
    }

    @GetMapping("/authentication")
    public String authentication(){
    
    
        return "authentication!!!";
    }

Configurar diferentes filtros

    filterChainDefinitionMap.put("/item/rememberMe","user");
    filterChainDefinitionMap.put("/item/authentication","authc");

Agregue un botón Recordarme a la página y agregue el efecto Recordarme al iniciar sesión.

<form action="/user/login" method="post">
    用户名:<input  name="username" />  <br />
    密码:<input name="password" />  <br />
    记住我:<input type="checkbox" name="rememberMe" value="on" />  <br />
    <button type="submit">登录</button>
</form>

Supongo que te gusta

Origin blog.csdn.net/qq_28314431/article/details/133045554
Recomendado
Clasificación