zoukankan      html  css  js  c++  java
  • Shiro 使用 JWT Token 配置类参考

    项目中使用了 Shiro 进行验证和授权,下面是 Shiro 配置类给予参考。

    后来并没有使用 Shiro,感觉使用 JWT 还是自己写拦截器比较灵活,使用 Shiro 后各种地方需要魔改,虽然功能也能实现,但感觉把简单问题复杂化了,如果单单只使用 Shiro 授权这一块可以尝试。

    package com.nwgdk.ums.config.shiro;
    
    import com.nwgdk.ums.config.shiro.filter.AccessTokenFilter;
    import com.nwgdk.ums.config.shiro.listener.CustomSessionListener;
    import com.nwgdk.ums.config.shiro.realm.AdminRealm;
    import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
    import org.apache.shiro.mgt.DefaultSubjectDAO;
    import org.apache.shiro.mgt.SecurityManager;
    import org.apache.shiro.session.SessionListener;
    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.mgt.DefaultWebSessionStorageEvaluator;
    import org.apache.shiro.web.servlet.SimpleCookie;
    import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
    import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.autoconfigure.AutoConfigureAfter;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.DependsOn;
    
    import javax.servlet.Filter;
    import java.util.*;
    
    /**
     * @author nwgdk
     */
    @Configuration
    @AutoConfigureAfter(ShiroLifecycleBeanPostProcessorConfiguartion.class)
    public class ShiroConfiguration {
    
        /**
         * Hash迭代次数
         */
        @Value("${ums.config.hash.hash-iterations}")
        private Integer hashIterations;
    
        /**
         * WEB 过滤器链
         */
        @Bean(name = "shiroFilter")
        public ShiroFilterFactoryBean shiroFilterFactoryBean() {
            ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
            // 设置安全管理器
            shiroFilterFactoryBean.setSecurityManager(securityManager());
            // 注册自定义过滤器
            Map<String, Filter> filterMap = new LinkedHashMap<>(8);
            filterMap.put("authc", new AccessTokenFilter());
            shiroFilterFactoryBean.setFilters(filterMap);
            // 定义过滤链
            Map<String, String> filterChains = new LinkedHashMap<>(8);
            filterChains.put("/v1/admin/login", "anon");
            filterChains.put("/**", "authc");
            // 设置过滤器链
            shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChains);
            return shiroFilterFactoryBean;
        }
    
        /**
         * 安全管理器
         */
        @Bean
        public SecurityManager securityManager() {
            DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
            // 设置 Session 管理器
            securityManager.setSessionManager(sessionManager());
            // 设置 Realm
            securityManager.setRealm(adminRealm());
            // 关闭 RememberMe
            securityManager.setRememberMeManager(null);
            // 设置自定义 Subject
            securityManager.setSubjectFactory(statelessDefaultSubjectFactory());
            // 设置 SubjectDao
            securityManager.setSubjectDAO(defaultSubjectDAO());
            return securityManager;
        }
    
        /**
         * 自定义 Subject 工厂, 禁止使用 Session
         */
        @Bean("subjectFactory")
        public StatelessDefaultSubjectFactory statelessDefaultSubjectFactory() {
            return new StatelessDefaultSubjectFactory();
        }
    
        @Bean
        public DefaultSubjectDAO defaultSubjectDAO() {
            DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
            // 设置会话存储调度器
            subjectDAO.setSessionStorageEvaluator(defaultWebSessionStorageEvaluator());
            return subjectDAO;
        }
    
        /**
         * 会话存储器
         */
        @Bean
        public DefaultWebSessionStorageEvaluator defaultWebSessionStorageEvaluator() {
            DefaultWebSessionStorageEvaluator evaluator = new DefaultWebSessionStorageEvaluator();
            // 禁用会话存储
            evaluator.setSessionStorageEnabled(false);
            return evaluator;
        }
    
        /**
         * Session 管理器
         */
        @Bean
        public DefaultWebSessionManager sessionManager() {
            DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
            // 设置 Cookie
            sessionManager.setSessionIdCookie(simpleCookie());
            // 启用 Session Id Cookie,默认启用
            sessionManager.setSessionIdCookieEnabled(false);
            // 设置全局超时时间,默认30分钟
            sessionManager.setGlobalSessionTimeout(1800000L);
            // 设置会话监听器
            sessionManager.setSessionListeners(customSessionListener());
            // 禁用 Session 验证调度器
            sessionManager.setSessionValidationSchedulerEnabled(false);
            return sessionManager;
        }
    
        /**
         * 会话监听器
         */
        @Bean
        public Collection<SessionListener> customSessionListener() {
            List<SessionListener> listeners = new ArrayList<>();
            listeners.add(new CustomSessionListener());
            return listeners;
        }
    
        /**
         * Session Cookie
         */
        @Bean
        public SimpleCookie simpleCookie() {
            SimpleCookie cookie = new SimpleCookie();
            // Session Cookie 名称
            cookie.setName("SID");
            // Session 存活时间
            cookie.setMaxAge(10);
            // 设置 Cookie 只读
            cookie.setHttpOnly(true);
            return cookie;
        }
    
        /**
         * 凭证匹配器
         */
        @Bean("credentialsMatcher")
        public HashedCredentialsMatcher hashedCredentialsMatcher() {
            HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
            // 散列算法
            hashedCredentialsMatcher.setHashAlgorithmName("md5");
            // 散列次数
            hashedCredentialsMatcher.setHashIterations(hashIterations);
            // 使用 HEX 编码
            hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);
            return hashedCredentialsMatcher;
        }
    
        /**
         * 领域对象
         */
        @Bean("adminRealm")
        public AdminRealm adminRealm() {
            AdminRealm adminRealm = new AdminRealm();
            // 设置密码匹配器
            adminRealm.setCredentialsMatcher(hashedCredentialsMatcher());
            return adminRealm;
        }
    
        /**
         * 开启注解 (如 @RequiresRoles, @RequiresPermissions),
         * 需借助 SpringAOP 扫描使用 Shiro 注解的类,并在必要时进行安全逻辑验证
         * 配置以下两个 Bean:
         * DefaultAdvisorAutoProxyCreator(可选) 和 AuthorizationAttributeSourceAdvisor 即可实现此功能
         */
        @Bean
        @DependsOn({"lifecycleBeanPostProcessor"})
        public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
            DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
            advisorAutoProxyCreator.setProxyTargetClass(true);
            return advisorAutoProxyCreator;
        }
    
        @Bean
        public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
            AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
            authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
            return authorizationAttributeSourceAdvisor;
        }
    }
    
    package com.nwgdk.ums.config.shiro;
    
    import org.apache.shiro.spring.LifecycleBeanPostProcessor;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * @author nwgdk
     */
    @Configuration
    public class ShiroLifecycleBeanPostProcessorConfiguartion {
    
        /**
         * Shiro 生命周期处理器
         */
        @Bean(name = "lifecycleBeanPostProcessor")
        public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
            return new LifecycleBeanPostProcessor();
        }
    }
    
    package com.nwgdk.ums.config.shiro;
    
    import org.apache.shiro.subject.Subject;
    import org.apache.shiro.subject.SubjectContext;
    import org.apache.shiro.web.mgt.DefaultWebSubjectFactory;
    
    /**
     * 自定义 Subject
     *
     * @author nwgdk
     */
    public class StatelessDefaultSubjectFactory extends DefaultWebSubjectFactory {
        @Override
        public Subject createSubject(SubjectContext context) {
            // 禁止 Subject 创建会话
            context.setSessionCreationEnabled(false);
            return super.createSubject(context);
        }
    }
    
  • 相关阅读:
    斐波那契数列 的两种实现方式(Java)
    单链表反转
    单链表合并
    两个有序list合并
    list去重 转载
    RemoveAll 要重写equals方法
    Java for LeetCode 138 Copy List with Random Pointer
    Java for LeetCode 137 Single Number II
    Java for LeetCode 136 Single Number
    Java for LeetCode 135 Candy
  • 原文地址:https://www.cnblogs.com/nwgdk/p/11116328.html
Copyright © 2011-2022 走看看