Shiro 整合 Springboo2.2

↘锁芯ラ 提交于 2020-01-13 08:12:40

Shiro

就不多介绍了,原理性的东西非常多。总结一下有一些要注意的点,例如AuthenticationAuthorization 这两个几乎长的一毛一样的单词对新手来说实在太不友好了。前者是登录时用的身份验证 (即用户密码),后者是 角色权限相关的验证

SpringBoot

网上很多教程是Spring的,一大堆 Bean 配置让人云里雾里的。 SpringBoot 出了 starter,我们可以用来省去一些配置。
注意pom引入的是上面那个带 web 的,不是下面那个,不然Web环境中用不了。算是个小小的坑
在这里插入图片描述

我们先来看一下,传统的Spring需要我们做哪些配置,即注入了哪些 Bean。

  1. 用来设置如何管理 session 的 seesionManger
  2. Shiro最核心的类,是所有相关类的门面,securityManager
  3. 拦截规则,设置哪些 url 需要进行 登录或权限 检查的 shiroFilter
  4. 下面两个是和Spring 相关的类,没有我们需要自定义的地方。

在这里插入图片描述

其实在Spring Boot 中 :
上面几个Bean都有对应的自动注入,从源代码中把他们扒出来,看看具体自动配置了什么。
ShiroWebAutoConfiguration 类中,有相关的自动配置。
在这里插入图片描述
例如这两个,具体的配置在父类。注意@ConditionalOnMissingBean 注解,意思是如果没有这个Bean,再进行注入,这是为了防止如果我们自已注入导致冲突,所以 Springboot 完全兼容了传统的Spring配置。

另两个Bean :

lifecycleBeanPostProcessor 是在 ShiroBeanAutoConfiguration 中注入的
在这里插入图片描述

看到没,和传统 Spring 的配置方法一毛一样,就是 new 了一下,只不过是Springboot 给我们自动注入的。
 
authorizationAttributeSourceAdvisor 是在 ShiroAnnotationProcessorAutoConfiguration 中自动注入的,代码就不贴了,会发现和传统Spring 配置的代码也是一毛一样。

那会不会我们就什么都不需要配置了?并不是,例如shiroFilterChainDefinition 虽然帮我们自动注入了,但是打开源码在这里插入图片描述
发现就简单的给我们拦截了所有的路径,都要进行登录!而在传统Spring中,一般我们会自已配置路由规则。所以要么我们干脆自己注入自定义后的Bean,覆盖掉它的自动注入。要么在环境中获取这个Bean,再进行自定义的修改。对应的代码为:
在这里插入图片描述
类似地,你可以自已配置其他Bean,下面给出传统Spring配置的方法便于参考。

/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有,侵权必究!
 */

package io.renren.common.config;

import io.renren.modules.sys.shiro.UserRealm;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.session.mgt.ServletContainerSessionManager;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Shiro的配置文件
 *
 * @author Mark sunlightcs@gmail.com
 */
@Configuration
public class ShiroConfig {

    /**
     * 集群环境,session交给spring-session管理
     */
    @Bean
    @ConditionalOnProperty(prefix = "renren", name = "cluster", havingValue = "true")
    public ServletContainerSessionManager servletContainerSessionManager() {
        return new ServletContainerSessionManager();
    }

    /**
     * ConditionalOnProperty 意思是 property 有 renren.cluster=false 配置,才执行下面的代码
     * 单机环境,session交给shiro管理
     */
    @Bean
    @ConditionalOnProperty(prefix = "renren", name = "cluster", havingValue = "false")
    public DefaultWebSessionManager sessionManager(@Value("${renren.globalSessionTimeout}") long globalSessionTimeout){
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        sessionManager.setSessionValidationSchedulerEnabled(true);
        sessionManager.setSessionIdUrlRewritingEnabled(false);
        sessionManager.setSessionValidationInterval(globalSessionTimeout * 1000);
        sessionManager.setGlobalSessionTimeout(globalSessionTimeout * 1000);
        return sessionManager;
    }

    @Bean("securityManager")
    public SecurityManager securityManager(UserRealm userRealm, SessionManager sessionManager) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(userRealm);
        securityManager.setSessionManager(sessionManager);
        securityManager.setRememberMeManager(null);
        return securityManager;
    }

    @Bean("shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);
        shiroFilter.setLoginUrl("/login.html");
        shiroFilter.setUnauthorizedUrl("/");

        Map<String, String> filterMap = new LinkedHashMap<>();
        filterMap.put("/swagger/**", "anon");
        filterMap.put("/v2/api-docs", "anon");
        filterMap.put("/swagger-ui.html", "anon");
        filterMap.put("/webjars/**", "anon");
        filterMap.put("/swagger-resources/**", "anon");

        filterMap.put("/statics/**", "anon");
        filterMap.put("/login.html", "anon");
        filterMap.put("/sys/login", "anon");
        filterMap.put("/favicon.ico", "anon");
        filterMap.put("/captcha.jpg", "anon");
        filterMap.put("/**", "authc");
        shiroFilter.setFilterChainDefinitionMap(filterMap);

        return shiroFilter;
    }

    @Bean("lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }
}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!