Shiro
就不多介绍了,原理性的东西非常多。总结一下有一些要注意的点,例如Authentication 和 Authorization 这两个几乎长的一毛一样的单词对新手来说实在太不友好了。前者是登录时用的身份验证 (即用户密码),后者是 角色权限相关的验证
SpringBoot
网上很多教程是Spring的,一大堆 Bean 配置让人云里雾里的。 SpringBoot 出了 starter,我们可以用来省去一些配置。
注意pom
引入的是上面那个带 web 的,不是下面那个,不然Web环境中用不了。算是个小小的坑
我们先来看一下,传统的Spring需要我们做哪些配置,即注入了哪些 Bean。
- 用来设置如何管理 session 的 seesionManger
- Shiro最核心的类,是所有相关类的门面,securityManager
- 拦截规则,设置哪些 url 需要进行 登录或权限 检查的 shiroFilter
- 下面两个是和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;
}
}
来源:CSDN
作者:Francis_null
链接:https://blog.csdn.net/qq_37186947/article/details/103846860