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.HashMap; 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(); } /** * 过滤器链 */ private Map filterChainDefinition() { Map map = MapUtil.newHashMap(20, true); map.put("/static/**", "anon"); map.put("/v1/login", "anon"); map.put("/v1/rsa-key", "anon"); map.put("/test/**", "anon"); map.put("/v1/**", "anon"); map.put("/**", "anon"); return map; } // @Bean // public JwtContext jwtUtil() { // return new JwtContext(this.properties); // } private Map filterMap() { HashMap map = MapUtil.newHashMap(); map.put("jwt", new JwtFilter(this.properties, this.jwtContext)); return map; } /** * Shiro过滤器 */ @Bean("shiroFilter") public ShiroFilterFactoryBean shiroFilterFactoryBean() { ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); shiroFilter.setSecurityManager(this.defaultWebSecurityManager()); shiroFilter.setFilters(this.filterMap()); shiroFilter.setFilterChainDefinitionMap(this.filterChainDefinition()); // 去掉,防止404路由自动跳转到登录请求 // shiroFilter.setLoginUrl("/v1/login"); // shiroFilter.setUnauthorizedUrl("/v1/login"); return shiroFilter; } }