package com.simuwang.base.config; import cn.hutool.core.map.MapUtil; import com.simuwang.base.components.ShiroLoginAuthAdapter; import com.simuwang.base.components.ShiroRsaCredentialsMatcher; import com.simuwang.base.components.UserAuthService; import com.simuwang.shiro.core.ShiroDbRealm; import com.simuwang.shiro.core.adapter.LoginAuthAdapter; import com.simuwang.shiro.core.bridge.AuthBridgeService; import com.simuwang.shiro.core.ShiroDbRealmImpl; import com.simuwang.shiro.core.jwt.JwtContext; import com.simuwang.shiro.core.jwt.JwtFilter; import jakarta.servlet.Filter; import org.apache.shiro.authc.credential.CredentialsMatcher; 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.servlet.SimpleCookie; import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn; import java.util.List; import java.util.List; import java.util.Map; @Configuration public class ShiroConfig { private final JwtContext jwtContext; private final DaqProperties properties; private final UserAuthService userAuthService; public ShiroConfig(JwtContext jwtContext, DaqProperties properties, UserAuthService userAuthService) { this.jwtContext = jwtContext; this.properties = properties; this.userAuthService = userAuthService; } /** * 保证实现了Shiro内部lifecycle函数的bean执行 */ @Bean(name = "lifecycleBeanPostProcessor") public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } /** * 注册的登录认证适配器,实际场景中需要自定义实现 * * @return / */ @Bean public LoginAuthAdapter authAdapter() { // return new SimpleLoginAuthAdapter(); return new ShiroLoginAuthAdapter(this.userAuthService); } @Bean public AuthBridgeService authBridgeService() { return new AuthBridgeService(this.authAdapter()); } /** * 创建cookie对象 */ @Bean(name = "sessionIdCookie") public SimpleCookie simpleCookie() { SimpleCookie simpleCookie = new SimpleCookie(); simpleCookie.setName("ShiroSession"); return simpleCookie; } /** * 权限管理器 */ @Bean(name = "securityManager") public DefaultWebSecurityManager defaultWebSecurityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(shiroDbRealm()); securityManager.setSessionManager(shiroSessionManager()); return securityManager; } /** * 自定义的密码匹配器,rsa * * @return / */ @Bean public CredentialsMatcher credentialsMatcher() { // HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(); // matcher.setHashAlgorithmName("SHA-256"); // matcher.setHashIterations(1000); // matcher.setStoredCredentialsHexEncoded(true); // return matcher; return new ShiroRsaCredentialsMatcher(this.properties); } /** * 自定义RealmImpl */ @Bean(name = "shiroDbRealm") public ShiroDbRealm shiroDbRealm() { return new ShiroDbRealmImpl(this.authBridgeService(), this.credentialsMatcher()); } /** * 会话管理器 */ @Bean(name = "sessionManager") public DefaultWebSessionManager shiroSessionManager() { DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); sessionManager.setSessionValidationSchedulerEnabled(false); sessionManager.setSessionIdCookieEnabled(true); sessionManager.setSessionIdCookie(simpleCookie()); sessionManager.setGlobalSessionTimeout(3600000); return sessionManager; } /** * AOP式方法级权限检查 */ @Bean @DependsOn("lifecycleBeanPostProcessor") public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); defaultAdvisorAutoProxyCreator.setProxyTargetClass(true); return defaultAdvisorAutoProxyCreator; } /** * 配合DefaultAdvisorAutoProxyCreator事项注解权限校验 */ @Bean public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor() { AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor(); aasa.setSecurityManager(defaultWebSecurityManager()); return new AuthorizationAttributeSourceAdvisor(); } /** * Shiro过滤器 */ @Bean("shiroFilter") public ShiroFilterFactoryBean shiroFilterFactoryBean() { ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); shiroFilter.setSecurityManager(this.defaultWebSecurityManager()); // 新增过滤器 Map filterMap = MapUtil.newHashMap(true); filterMap.put("jwt", new JwtFilter(this.jwtContext)); shiroFilter.setFilters(filterMap); // 过滤器链配置 Map filterChainMap = MapUtil.newHashMap(16, true); List shiroFilterChain = this.properties.getShiroFilterChain(); for (DaqProperties.FilterChain filterChain : shiroFilterChain) { filterChainMap.put(filterChain.getPath(), String.join(",", filterChain.getFilters())); } shiroFilter.setFilterChainDefinitionMap(filterChainMap); // 去掉,防止404路由自动跳转到登录请求 // shiroFilter.setLoginUrl("/v1/login"); // shiroFilter.setUnauthorizedUrl("/v1/login"); return shiroFilter; } }