SpringBoot+Shiro+JWT权限管理
Shiro
- Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。
- 使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。
三个核心组件:Subject, SecurityManager 和 Realms.
- Subject代表了当前用户的安全操作,即“当前操作用户”。
- SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。
- Realm: Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。
- ShiroBasicArchitecture
JWT
- JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案
- JSON Web令牌是一种开放的行业标准 RFC 7519方法,用于在双方之间安全地表示声明。
JWT 数据结构
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJodHRwczovL3NwcmluZ2Jvb3QucGx1cyIsIm5hbWUiOiJzcHJpbmctYm9vdC1wbHVzIiwiaWF0IjoxNTE2MjM5MDIyfQ.1Cm7Ej8oIy1P5pkpu8-Q0B7bTU254I1og-ZukEe84II
JWT有三部分组成:Header:头部,Payload:负载,Signature:签名
SpringBoot+Shiro+JWT
pom.xml Shiro依赖
org.apache.shiro shiro-spring-boot-starter 1.4.1
pom.xml JWT依赖
com.auth0 java-jwt 3.8.3
ShiroConfig.java配置
@Slf4j@Configurationpublic class ShiroConfig { /** * JWT过滤器名称 */ private static final String JWT_FILTER_NAME = "jwtFilter"; /** * Shiro过滤器名称 */ private static final String SHIRO_FILTER_NAME = "shiroFilter"; @Bean public CredentialsMatcher credentialsMatcher() { return new JwtCredentialsMatcher(); } /** * JWT数据源验证 * * @return */ @Bean public JwtRealm jwtRealm(LoginRedisService loginRedisService) { JwtRealm jwtRealm = new JwtRealm(loginRedisService); jwtRealm.setCachingEnabled(false); jwtRealm.setCredentialsMatcher(credentialsMatcher()); return jwtRealm; } /** * 禁用session * * @return */ @Bean public DefaultSessionManager sessionManager() { DefaultSessionManager manager = new DefaultSessionManager(); manager.setSessionValidationSchedulerEnabled(false); return manager; } @Bean public SessionStorageEvaluator sessionStorageEvaluator() { DefaultSessionStorageEvaluator sessionStorageEvaluator = new DefaultWebSessionStorageEvaluator(); sessionStorageEvaluator.setSessionStorageEnabled(false); return sessionStorageEvaluator; } @Bean public DefaultSubjectDAO subjectDAO() { DefaultSubjectDAO defaultSubjectDAO = new DefaultSubjectDAO(); defaultSubjectDAO.setSessionStorageEvaluator(sessionStorageEvaluator()); return defaultSubjectDAO; } /** * 安全管理器配置 * * @return */ @Bean public DefaultWebSecurityManager securityManager(LoginRedisService loginRedisService) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(jwtRealm(loginRedisService)); securityManager.setSubjectDAO(subjectDAO()); securityManager.setSessionManager(sessionManager()); SecurityUtils.setSecurityManager(securityManager); return securityManager; } /** * ShiroFilterFactoryBean配置 * * @param securityManager * @param loginRedisService * @param shiroProperties * @param jwtProperties * @return */ @Bean(SHIRO_FILTER_NAME) public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager, LoginService loginService, LoginRedisService loginRedisService, ShiroProperties shiroProperties, JwtProperties jwtProperties) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); Map filterMap = new HashedMap(); filterMap.put(JWT_FILTER_NAME, new JwtFilter(loginService, loginRedisService, jwtProperties)); shiroFilterFactoryBean.setFilters(filterMap); Map filterChainMap = shiroFilterChainDefinition(shiroProperties).getFilterChainMap(); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainMap); return shiroFilterFactoryBean; } /** * Shiro路径权限配置 * * @return */ @Bean public ShiroFilterChainDefinition shiroFilterChainDefinition(ShiroProperties shiroProperties) { DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition(); // 获取ini格式配置 String definitions = shiroProperties.getFilterChainDefinitions(); if (StringUtils.isNotBlank(definitions)) { Map section = IniUtil.parseIni(definitions); log.debug("definitions:{}