Shiro class reference using JWT Token Configuration

The item is used for authentication and authorization Shiro, Shiro configuration classes are given below reference.

Later did not use Shiro, feeling JWT use or write your own interceptor more flexible, the use of a variety of local Shiro need magic to change, although the function can be achieved, but it feels to complicate the simple question, if only this one only authorized the use of Shiro Can try.

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);
    }
}

Guess you like

Origin www.cnblogs.com/nwgdk/p/11116328.html