ShiroConfig完整配置案例

tech2025-04-21  6

package cn.com.suntree.treetask.config; import cn.com.suntree.common.ding.model.DingUserDo; import cn.com.suntree.common.entity.SysUser; import cn.com.suntree.common.entity.returnvo.PowerVo; import cn.com.suntree.common.entity.returnvo.RoleVo; import cn.com.suntree.common.mapper.DingUserMapper; import cn.com.suntree.common.mapper.RoleMapper; import cn.com.suntree.common.service.CmpUserService; import cn.com.suntree.common.service.MenuService; import cn.com.suntree.common.utils.YAMLUtils; import cn.com.suntree.utils.myself.CommonUtil; import lombok.extern.log4j.Log4j2; import org.apache.shiro.authc.*; import org.apache.shiro.authc.credential.CredentialsMatcher; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.session.Session; import org.apache.shiro.session.UnknownSessionException; import org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler; import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO; import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.apache.shiro.web.servlet.SimpleCookie; import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; import org.crazycake.shiro.RedisCacheManager; import org.crazycake.shiro.RedisManager; import org.crazycake.shiro.RedisSessionDAO; import org.crazycake.shiro.SerializeUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; import javax.servlet.Filter; import java.io.Serializable; import java.util.*; @Log4j2 @Configuration public class ShiroConfig { /** * @param securityManager * @return 拦截工厂配置 */ @Bean public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); // 必须设置 SecurityManager shiroFilterFactoryBean.setSecurityManager(securityManager); //自定义拦截器 Map<String, Filter> filtersMap = new LinkedHashMap<String, Filter>(); shiroFilterFactoryBean.setFilters(filtersMap); //权限控制map HashMap<String, String> filterMap = new LinkedHashMap<>(); filterMap.put("/api/enclosure/download", "anon"); filterMap.put("/api/register/**", "anon") filterMap.put("/api/delay/**","anon"); filterMap.put("/api/**", "authc"); shiroFilterFactoryBean.setLoginUrl("/login"); shiroFilterFactoryBean.setUnauthorizedUrl("/codelogin");//验证码登陆 shiroFilterFactoryBean.setUnauthorizedUrl("/ddlogin/**");//验证码登陆 shiroFilterFactoryBean.setUnauthorizedUrl("/error"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap); return shiroFilterFactoryBean; } /** * @return 安全管理器 */ @Bean public SecurityManager securityManager(@Qualifier("myShiroRealm") MyShiroRealm myShiroRealm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); // 自定义缓存实现 使用redis securityManager.setCacheManager(cacheManager()); // 自定义session管理 使用redis securityManager.setSessionManager(sessionManager()); // 设置realm. securityManager.setRealm(myShiroRealm); return securityManager; } /** * 身份认证realm; (这个需要自己写,账号密码校验;权限等) * * @return */ @Bean public MyShiroRealm myShiroRealm() { MyShiroRealm myShiroRealm = new MyShiroRealm(); myShiroRealm.setCredentialsMatcher(credentialsMatcher()); myShiroRealm.setCacheManager(cacheManager());//設置緩存 return myShiroRealm; } /** * cacheManager 缓存 redis实现 * 使用的是shiro-redis开源插件 * * @return */ public RedisCacheManager cacheManager() { RedisCacheManager redisCacheManager = new RedisCacheManager(); redisCacheManager.setRedisManager(redisManager()); return redisCacheManager; } /** * 配置shiro redisManager * 使用的是shiro-redis开源插件 * * @return */ public RedisManager redisManager() { RedisManager redisManager = new RedisManager(); redisManager.setHost(host); redisManager.setPort(port); redisManager.setExpire(expireTm);// 配置缓存过期时间 redisManager.setTimeout(0); redisManager.setPassword(passwd); return redisManager; } //浏览器会话的cookie管理 @Bean(name = "sessionIdCookie") public SimpleCookie sessionIdCookie() { SimpleCookie cookie = new SimpleCookie(); cookie.setName("WEBS"); cookie.setHttpOnly(true); cookie.setMaxAge(-1);//浏览器关闭时失效此Cookie; return cookie; } /** * Session Manager * 使用的是shiro-redis开源插件 */ @Bean public DefaultWebSessionManager sessionManager() { DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); sessionManager.setGlobalSessionTimeout(28800000L); // sessionManager.setGlobalSessionTimeout(60000L); sessionManager.setSessionIdCookieEnabled(true); sessionManager.setSessionValidationScheduler(getExecutorServiceSessionValidationScheduler()); sessionManager.setSessionIdCookie(sessionIdCookie()); sessionManager.setSessionDAO(redisSessionDAO()); return sessionManager; } @Bean(name = "sessionValidationScheduler") public ExecutorServiceSessionValidationScheduler getExecutorServiceSessionValidationScheduler() { ExecutorServiceSessionValidationScheduler scheduler = new ExecutorServiceSessionValidationScheduler(); scheduler.setInterval(900000); return scheduler; } /** * 区分趣任务和趣乐部登陆session */ public class MyRedisSessionDAO extends RedisSessionDAO { private Logger logger = LoggerFactory.getLogger(MyRedisSessionDAO.class); private RedisManager redisManager; //趣任务登陆会话所属key前缀 private String keyPrefix = "cmp_shiro_redis_session:"; public MyRedisSessionDAO() { } public void update(Session session) throws UnknownSessionException { this.saveSession(session); } private void saveSession(Session session) throws UnknownSessionException { if (session != null && session.getId() != null) { byte[] key = this.getByteKey(session.getId()); byte[] value = SerializeUtils.serialize(session); session.setTimeout((long) (this.redisManager.getExpire() * 1000)); this.redisManager.set(key, value, this.redisManager.getExpire()); } else { logger.error("session or session id is null"); } } public void delete(Session session) { if (session != null && session.getId() != null) { this.redisManager.del(this.getByteKey(session.getId())); } else { logger.error("session or session id is null"); } } public Collection<Session> getActiveSessions() { Set<Session> sessions = new HashSet(); Set<byte[]> keys = this.redisManager.keys(this.keyPrefix + "*"); if (keys != null && keys.size() > 0) { Iterator i$ = keys.iterator(); while (i$.hasNext()) { byte[] key = (byte[]) i$.next(); Session s = (Session) SerializeUtils.deserialize(this.redisManager.get(key)); sessions.add(s); } } return sessions; } protected Serializable doCreate(Session session) { Serializable sessionId = this.generateSessionId(session); this.assignSessionId(session, sessionId); this.saveSession(session); return sessionId; } protected Session doReadSession(Serializable sessionId) { if (sessionId == null) { logger.error("session id is null"); return null; } else { Session s = (Session) SerializeUtils.deserialize(this.redisManager.get(this.getByteKey(sessionId))); return s; } } private byte[] getByteKey(Serializable sessionId) { String preKey = this.keyPrefix + sessionId; return preKey.getBytes(); } public RedisManager getRedisManager() { return this.redisManager; } public void setRedisManager(RedisManager redisManager) { this.redisManager = redisManager; this.redisManager.init(); } public String getKeyPrefix() { return this.keyPrefix; } public void setKeyPrefix(String keyPrefix) { this.keyPrefix = keyPrefix; } } /** * RedisSessionDAO shiro sessionDao层的实现 通过redis * 使用的是shiro-redis开源插件 */ @Bean public MyRedisSessionDAO redisSessionDAO() { MyRedisSessionDAO redisSessionDAO = new MyRedisSessionDAO(); //自定义sessionId生成器 //redisSessionDAO.setSessionIdGenerator(mySessionIdGenerstor()); redisSessionDAO.setRedisManager(redisManager()); return redisSessionDAO; } /* @Bean public MySessionIdGenerstor mySessionIdGenerstor(){ return new MySessionIdGenerstor(); }*/ /*** * 授权所用配置 * * @return */ @Bean public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator(); defaultAAP.setProxyTargetClass(true); return defaultAAP; } /** * @param securityManager * @return 授权注解支持 */ @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } /** * Shiro生命周期处理器 @Bean public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } */ /** * @return 密码匹配器 */ @Bean public CredentialsMatcher credentialsMatcher() { HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(); hashedCredentialsMatcher.setHashAlgorithmName("md5"); return hashedCredentialsMatcher; } /** * 自定义 - 数据域 */ public class MyShiroRealm extends AuthorizingRealm { @Autowired @Lazy private CmpUserService userService; @Autowired @Lazy private RoleMapper roleMapper; /** * @param principalCollection * @return * @implNote 功能授权 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { SysUser user = (SysUser) principalCollection.getPrimaryPrincipal(); SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); /* user = userService.getUserDetailInfoByUserId(user.getUserID(), user.getCompanyId()); List<RoleVo> roleList = user.getRoleList(); for (RoleVo role : roleList) { authorizationInfo.addRole(role.getRoleName()); if (CommonUtil.check(role.getPowerList())) { for (PowerVo permission : role.getPowerList()) { authorizationInfo.addStringPermission(permission.getUrl()); } } }*/ authorizationInfo.setRoles(new HashSet<>(userService.listRoleNameByUser(user))); authorizationInfo.setStringPermissions(new HashSet<>(userService.listPowerNameByUser(user))); return authorizationInfo; } /** * @param authenticationToken * @return * @throws AuthenticationException * @implNote 身份认证 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { String key = (String) authenticationToken.getPrincipal(); boolean isPhomeToken = authenticationToken instanceof AuthenticationTokenMobilePhone; SysUser u = new SysUser(); u.setAccNum(key); SysUser user = isPhomeToken ? ((AuthenticationTokenMobilePhone) authenticationToken).getUser() : userService.getUserByAcc(u); if (user == null) { throw new UnknownAccountException(); } else if ("0".equals(user.getIsLock())) { throw new LockedAccountException(); // 帐号冻结,非正常 } String credentials = isPhomeToken ? "d036a5788f9ffade1893be5eb5cee798" : user.getPasswd(); if(!CommonUtil.checkStr(credentials) || user.getIsActive()==0){ throw new AuthenticationException("该账号未激活,请先注册激活"); } SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(user, credentials, this.getName()); return simpleAuthenticationInfo; } @Override public boolean supports(AuthenticationToken token) {// 支持多种验证因子 return true; } } }
最新回复(0)