XiaoRuby
2023-08-07 d8a687741273d121586b83745280c57f7e9d3297
user-server/src/main/java/com/yuanchu/limslaboratory/shiro/config/ShiroConfig.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,179 @@
package com.yuanchu.limslaboratory.shiro.config;
import com.yuanchu.limslaboratory.shiro.filter.JwtFilter;
import com.yuanchu.limslaboratory.shiro.MultiRealmAuthenticator;
import com.yuanchu.limslaboratory.shiro.realm.JwtRealm;
import com.yuanchu.limslaboratory.shiro.realm.ShiroRealm;
import com.yuanchu.limslaboratory.shiro.utils.JwtCredentialsMatcher;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authc.pam.AuthenticationStrategy;
import org.apache.shiro.authc.pam.FirstSuccessfulStrategy;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.authz.Authorizer;
import org.apache.shiro.authz.ModularRealmAuthorizer;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.mgt.SessionStorageEvaluator;
import org.apache.shiro.realm.Realm;
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.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
import java.util.*;
@Configuration
public class ShiroConfig {
    /**
     * ä¸å‘ Spring容器中注册 JwtFilter Bean,防止 Spring å°† JwtFilter æ³¨å†Œä¸ºå…¨å±€è¿‡æ»¤å™¨
     * å…¨å±€è¿‡æ»¤å™¨ä¼šå¯¹æ‰€æœ‰è¯·æ±‚进行拦截,而本例中只需要拦截除 /login å’Œ /logout å¤–的请求
     * å¦ä¸€ç§ç®€å•做法是:直接去掉 jwtFilter()上的 @Bean æ³¨è§£
     */
    @Bean
    public FilterRegistrationBean<Filter> registration(JwtFilter filter) {
        FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<Filter>(filter);
        registration.setEnabled(false);
        return registration;
    }
    //ShiroFilter过滤所有请求
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //给ShiroFilter配置安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        // æ·»åŠ  jwt ä¸“用过滤器,拦截除 /login å’Œ /logout å¤–的请求
        Map<String, Filter> filterMap = new LinkedHashMap<>();
        filterMap.put("jwtFilter", new JwtFilter());
        shiroFilterFactoryBean.setFilters(filterMap);
        //配置系统公共资源
        Map<String, String> map = new HashMap<String, String>();
        // swagger放行
        map.put("/doc.html", "anon");
        map.put("/webjars/**/**", "anon");
        map.put("/swagger-resources", "anon");
        map.put("/api-docs", "anon");
        map.put("/v3/**", "anon");
        map.put("/link-basic/*", "anon");
        map.put("/user/login/**","anon");//表示这个为公共资源 ä¸€å®šæ˜¯åœ¨å—限资源上面
//        map.put("/**","jwtFilter");//表示这个资源需要认证和授权
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }
    /**
     * é…ç½® ModularRealmAuthenticator
     */
    @Bean
    public ModularRealmAuthenticator authenticator() {
        ModularRealmAuthenticator authenticator = new MultiRealmAuthenticator();
        // è®¾ç½®å¤š Realm的认证策略,默认 AtLeastOneSuccessfulStrategy
        AuthenticationStrategy strategy = new FirstSuccessfulStrategy();
        authenticator.setAuthenticationStrategy(strategy);
        return authenticator;
    }
    /**
     * ç¦ç”¨session, ä¸ä¿å­˜ç”¨æˆ·ç™»å½•状态。保证每次请求都重新认证
     */
    @Bean
    protected SessionStorageEvaluator sessionStorageEvaluator() {
        DefaultSessionStorageEvaluator sessionStorageEvaluator = new DefaultSessionStorageEvaluator();
        sessionStorageEvaluator.setSessionStorageEnabled(false);
        return sessionStorageEvaluator;
    }
    /**
     * é…ç½® SecurityManager:权限管理器
     */
    @Bean
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 1.身份验证器
        securityManager.setAuthenticator(authenticator());
        // 2.管理Realm
        List<Realm> realms = new ArrayList<Realm>(16);
        realms.add(JwtRealm());
        realms.add(shiroRealm());
        securityManager.setRealms(realms); // é…ç½®å¤šä¸ªrealm
        // 3.关闭shiro自带的session
        DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
        subjectDAO.setSessionStorageEvaluator(sessionStorageEvaluator());
        securityManager.setSubjectDAO(subjectDAO);
        return securityManager;
    }
    //    åˆ›å»ºè‡ªå®šä¹‰Realm
    @Bean
    public Realm shiroRealm() {
        ShiroRealm realm = new ShiroRealm();
//        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
////        //设置使用MD5加密算法
////        credentialsMatcher.setHashAlgorithmName(Md5Hash.ALGORITHM_NAME);
////        //散列次数
////        credentialsMatcher.setHashIterations(1024);
//        realm.setCredentialsMatcher(credentialsMatcher);
        return realm;
    }
    @Bean
    public Realm JwtRealm(){
        JwtRealm jwtRealm = new JwtRealm();
        // è®¾ç½®åŠ å¯†ç®—æ³•
        CredentialsMatcher credentialsMatcher = new JwtCredentialsMatcher();
        // è®¾ç½®åŠ å¯†æ¬¡æ•°
        jwtRealm.setCredentialsMatcher(credentialsMatcher);
        return jwtRealm;
    }
    // ä»¥ä¸‹ä¸‰ä¸­bean通用,固定配置
    /**
     * äº¤ç”± Spring æ¥è‡ªåŠ¨åœ°ç®¡ç† Shiro-Bean çš„生命周期
     */
    @Bean
    public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }
    /**
     * ä¸º Spring-Bean å¼€å¯å¯¹ Shiro æ³¨è§£çš„æ”¯æŒ
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
    /**
     * å¼€å¯AOP方法级权限检查
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }
}