|
@@ -0,0 +1,216 @@
|
|
|
+/**
|
|
|
+ * MIT License
|
|
|
+ * Copyright (c) 2018 yadong.zhang
|
|
|
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
+ * of this software and associated documentation files (the "Software"), to deal
|
|
|
+ * in the Software without restriction, including without limitation the rights
|
|
|
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
+ * copies of the Software, and to permit persons to whom the Software is
|
|
|
+ * furnished to do so, subject to the following conditions:
|
|
|
+ * The above copyright notice and this permission notice shall be included in all
|
|
|
+ * copies or substantial portions of the Software.
|
|
|
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
+ * SOFTWARE.
|
|
|
+ */
|
|
|
+package com.usky.config.shiro;
|
|
|
+
|
|
|
+import org.apache.shiro.authc.credential.CredentialsMatcher;
|
|
|
+import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
|
|
|
+import org.apache.shiro.mgt.SecurityManager;
|
|
|
+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.crazycake.shiro.*;
|
|
|
+import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.beans.factory.annotation.Qualifier;
|
|
|
+import org.springframework.beans.factory.config.MethodInvokingFactoryBean;
|
|
|
+import org.springframework.context.annotation.Bean;
|
|
|
+import org.springframework.context.annotation.Configuration;
|
|
|
+import org.springframework.context.annotation.DependsOn;
|
|
|
+import org.springframework.core.annotation.Order;
|
|
|
+import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
+import redis.clients.jedis.HostAndPort;
|
|
|
+import redis.clients.jedis.JedisCluster;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.util.HashSet;
|
|
|
+import java.util.LinkedHashMap;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Set;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Shiro配置类
|
|
|
+ *
|
|
|
+ * @author yadong.zhang (yadong.zhang0415(a)gmail.com)
|
|
|
+ * @version 1.0
|
|
|
+ * @website https://www.zhyd.me
|
|
|
+ * @date 2018/4/24 14:37
|
|
|
+ * @since 1.0
|
|
|
+ */
|
|
|
+@Configuration
|
|
|
+@Order(-1)
|
|
|
+public class ShiroConfig {
|
|
|
+ @Resource
|
|
|
+ LettuceConnectionFactory lettuceConnectionFactory;
|
|
|
+
|
|
|
+ @Bean
|
|
|
+ public MethodInvokingFactoryBean methodInvokingFactoryBean(@Qualifier("MysecurityManager") DefaultWebSecurityManager securityManager) {
|
|
|
+ MethodInvokingFactoryBean bean = new MethodInvokingFactoryBean();
|
|
|
+ bean.setStaticMethod("org.apache.shiro.SecurityUtils.setSecurityManager");
|
|
|
+ bean.setArguments(securityManager);
|
|
|
+ return bean;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Bean(name = "lifecycleBeanPostProcessor")
|
|
|
+ public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
|
|
|
+ return new LifecycleBeanPostProcessor();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Bean(name = "shiroFilter")
|
|
|
+ public ShiroFilterFactoryBean shirFilter(@Qualifier("MysecurityManager") DefaultWebSecurityManager securityManager) {
|
|
|
+ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
|
|
|
+ // 必须设置 SecurityManager
|
|
|
+ shiroFilterFactoryBean.setSecurityManager(securityManager);
|
|
|
+ // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
|
|
|
+ // shiroFilterFactoryBean.setLoginUrl("");
|
|
|
+ // 登录成功后要跳转的链接
|
|
|
+ // shiroFilterFactoryBean.setSuccessUrl("");
|
|
|
+ // 未授权界面;
|
|
|
+ shiroFilterFactoryBean.setUnauthorizedUrl("/error/403");
|
|
|
+ LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
|
|
|
+ filterChainDefinitionMap.put("/doc.html", "anon");
|
|
|
+ filterChainDefinitionMap.put("/sys/login", "anon");
|
|
|
+ filterChainDefinitionMap.put("/**/*.js", "anon");
|
|
|
+ filterChainDefinitionMap.put("/**/*.css", "anon");
|
|
|
+ filterChainDefinitionMap.put("/**/*.html", "anon");
|
|
|
+ filterChainDefinitionMap.put("/**/*.svg", "anon");
|
|
|
+ filterChainDefinitionMap.put("/**/*.pdf", "anon");
|
|
|
+ filterChainDefinitionMap.put("/**/*.jpg", "anon");
|
|
|
+ filterChainDefinitionMap.put("/**/*.png", "anon");
|
|
|
+ filterChainDefinitionMap.put("/**/*.ico", "anon");
|
|
|
+ filterChainDefinitionMap.put("/**/*.ttf", "anon");
|
|
|
+ filterChainDefinitionMap.put("/**/*.woff", "anon");
|
|
|
+ filterChainDefinitionMap.put("/**/*.woff2", "anon");
|
|
|
+ filterChainDefinitionMap.put("/druid/**", "anon");
|
|
|
+ filterChainDefinitionMap.put("/swagger-ui.html", "anon");
|
|
|
+ filterChainDefinitionMap.put("/swagger**/**", "anon");
|
|
|
+ filterChainDefinitionMap.put("/webjars/**", "anon");
|
|
|
+ filterChainDefinitionMap.put("/v2/**", "anon");
|
|
|
+ // filterChainDefinitionMap.put("/**", "authc");
|
|
|
+ shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
|
|
|
+ return shiroFilterFactoryBean;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Bean
|
|
|
+ @DependsOn("lifecycleBeanPostProcessor")
|
|
|
+ public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
|
|
|
+ DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
|
|
|
+ creator.setProxyTargetClass(true);
|
|
|
+ return creator;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Bean(name = "MysecurityManager")
|
|
|
+ public DefaultWebSecurityManager securityManager(@Qualifier("shiroRealm") ShiroRealm authRealm) {
|
|
|
+ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
|
|
|
+ // 设置realm.
|
|
|
+ securityManager.setRealm(authRealm);
|
|
|
+ securityManager.setCacheManager(redisCacheManager());
|
|
|
+ // 自定义session管理 使用redis
|
|
|
+ securityManager.setSessionManager(sessionManager());
|
|
|
+ return securityManager;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Bean(name = "shiroRealm")
|
|
|
+ public ShiroRealm shiroRealm(@Qualifier("credentialsMatcher") CredentialsMatcher matcher) {
|
|
|
+ ShiroRealm shiroRealm = new ShiroRealm();
|
|
|
+ shiroRealm.setCredentialsMatcher(credentialsMatcher());
|
|
|
+ return shiroRealm;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 凭证匹配器
|
|
|
+ */
|
|
|
+ @Bean(name = "credentialsMatcher")
|
|
|
+ public CredentialsMatcher credentialsMatcher() {
|
|
|
+ HashedCredentialsMatcher hashedMatcher = new HashedCredentialsMatcher();
|
|
|
+ hashedMatcher.setHashAlgorithmName("md5");
|
|
|
+// hashedMatcher.setHashIterations(1);
|
|
|
+ return hashedMatcher;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 开启shiro aop注解支持.
|
|
|
+ * 使用代理方式;所以需要开启代码支持;
|
|
|
+ *
|
|
|
+ * @param securityManager
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Bean
|
|
|
+ public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
|
|
|
+ AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
|
|
|
+ authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
|
|
|
+ return authorizationAttributeSourceAdvisor;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Bean
|
|
|
+ public RedisManager redisManager() {
|
|
|
+ RedisManager manager;
|
|
|
+ RedisManager redisManager = new RedisManager();
|
|
|
+ redisManager.setHost(lettuceConnectionFactory.getHostName());
|
|
|
+ redisManager.setPort(lettuceConnectionFactory.getPort());
|
|
|
+ redisManager.setDatabase(1);
|
|
|
+ redisManager.setTimeout(0);
|
|
|
+ if (!StringUtils.isEmpty(lettuceConnectionFactory.getPassword())) {
|
|
|
+ redisManager.setPassword(lettuceConnectionFactory.getPassword());
|
|
|
+ }
|
|
|
+ manager = redisManager;
|
|
|
+
|
|
|
+ return manager;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * cacheManager 缓存 redis实现
|
|
|
+ * 使用的是shiro-redis开源插件
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Bean
|
|
|
+ public RedisCacheManager redisCacheManager() {
|
|
|
+ RedisCacheManager redisCacheManager = new RedisCacheManager();
|
|
|
+ redisCacheManager.setPrincipalIdFieldName("userId");
|
|
|
+ redisCacheManager.setRedisManager(redisManager());
|
|
|
+ return redisCacheManager;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * RedisSessionDAO shiro sessionDao层的实现 通过redis
|
|
|
+ * 使用的是shiro-redis开源插件
|
|
|
+ */
|
|
|
+// @Bean
|
|
|
+ public RedisSessionDAO redisSessionDAO() {
|
|
|
+ RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
|
|
|
+ redisSessionDAO.setRedisManager(redisManager());
|
|
|
+ return redisSessionDAO;
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * shiro session的管理
|
|
|
+ */
|
|
|
+ @Bean
|
|
|
+ public DefaultWebSessionManager sessionManager() {
|
|
|
+ DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
|
|
|
+ sessionManager.setGlobalSessionTimeout(2592000 * 1000L);
|
|
|
+ sessionManager.setSessionDAO(redisSessionDAO());
|
|
|
+ return sessionManager;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|