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);
        }
    }
    
  • 相关阅读:
    [NOI2004] 郁闷的出纳员
    对象内部套嵌多个对象
    函数
    匿名函数、对象
    函数部分
    Html部分
    搜索二叉树的应用
    二叉树的线索化
    搜索结构搜索二叉树
    堆与最优级队列
  • 原文地址:https://www.cnblogs.com/nwgdk/p/11116328.html
Copyright © 2011-2022 走看看