jiangping
2023-08-29 1812198cdb63b5b9da27c20e5606343b7ba73091
redis缓存session
已添加1个文件
已删除1个文件
已修改13个文件
已重命名11个文件
623 ■■■■ 文件已修改
server/src/main/java/doumeemes/config/mybatis/MyBatisInterceptor.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/shiro/ShiroAuthFilter.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/shiro/ShiroCache.java 76 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/shiro/ShiroCacheManager.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/shiro/ShiroConfig.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/shiro/ShiroCredentialsMatcher.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/shiro/ShiroRealm.java 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/shiro/ShiroRedisSessionDAO.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/shiro/ShiroSessionDAO.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/shiro/ShiroSessionManager.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/shiro/ShiroSessionSerializer.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/shiro/ShiroToken.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/shiro/ShiroTokenManager.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/shiroMemory/ShiroAuthFilter.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/shiroMemory/ShiroCache.java 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/shiroMemory/ShiroCacheManager.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/shiroMemory/ShiroConfig.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/shiroMemory/ShiroCredentialsMatcher.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/shiroMemory/ShiroRealm.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/shiroMemory/ShiroSessionDAO.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/shiroMemory/ShiroSessionManager.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/shiroMemory/ShiroToken.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/shiroMemory/ShiroTokenManager.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/shiroRedis/ShiroCache.java 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/service/system/impl/SystemLoginServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/service/system/impl/WxLoginServiceImpl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/mybatis/MyBatisInterceptor.java
@@ -118,6 +118,11 @@
     * @date 2022/04/18 18:12
     */
    private LoginUserInfo getLoginUser () {
        try {
        return (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
        }catch (Exception e){
            return  null;
        }
    }
}
server/src/main/java/doumeemes/config/shiro/ShiroAuthFilter.java
@@ -1,9 +1,10 @@
package doumeemes.config.shiro;
import doumeemes.core.model.ApiResponse;
import com.alibaba.fastjson.JSON;
import doumeemes.core.model.ApiResponse;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
@@ -12,7 +13,7 @@
/**
 * Shiro认证过滤器,处理未认证情况的响应
 * @author Eva.Caesar Liu
 * @date 2022/04/18 18:12
 * @date 2023/04/17 12:11
 */
public class ShiroAuthFilter extends FormAuthenticationFilter {
server/src/main/java/doumeemes/config/shiro/ShiroCache.java
@@ -1,34 +1,38 @@
package doumeemes.config.shiro;
import doumeemes.service.proxy.CacheProxy;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.springframework.beans.factory.annotation.Autowired;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.CollectionUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
 * Shiro缓存
 * @author Eva.Caesar Liu
 * @date 2022/04/18 18:12
 * @date 2023/04/17 12:11
 */
//@Scope(value = "prototype")
@Scope(value = "prototype")
@Slf4j
//@Component
@Component
public class ShiroCache implements Cache<Object, Serializable> {
    private String keyPrefix = "";
    @Autowired
    private CacheProxy<Object, Serializable> cacheProxy;
    @Resource(name="sessionRedisTemplate")
    private RedisTemplate<Object, Serializable> redisTemplate;
    public ShiroCache () {
        log.debug("ShiroCache: new, keyPrefix = [" + keyPrefix + "]");
@@ -44,7 +48,7 @@
        if (key == null) {
            return null;
        }
        return cacheProxy.get(getKey(key));
        return redisTemplate.opsForValue().get(getKey(key));
    }
    @Override
@@ -52,7 +56,7 @@
        if (key == null) {
            return null;
        }
        cacheProxy.put(getKey(key), value);
        redisTemplate.opsForValue().set(getKey(key), value);
        return value;
    }
@@ -60,14 +64,14 @@
        if (key == null) {
            return null;
        }
        cacheProxy.put(getKey(key), value, timeout);
        redisTemplate.opsForValue().set(getKey(key), value, timeout, TimeUnit.SECONDS);
        return value;
    }
    @Override
    public void clear() throws CacheException {
        Set<Object> keys = this.keys();
        cacheProxy.remove(keys);
        redisTemplate.delete(keys);
    }
    @Override
@@ -77,7 +81,7 @@
    @Override
    public Set<Object> keys() {
        Set<Object> keys = cacheProxy.keys(keyPrefix + "*");
        Set<Object> keys = redisTemplate.keys(keyPrefix + "*");
        if (CollectionUtils.isEmpty(keys)) {
            return Collections.emptySet();
        }
@@ -92,7 +96,7 @@
            return values;
        }
        for (Object k : keys) {
            values.add(cacheProxy.get(k));
            values.add(redisTemplate.opsForValue().get(k));
        }
        return values;
    }
@@ -103,11 +107,53 @@
            return null;
        }
        Serializable value = this.get(getKey(key));
        cacheProxy.remove(getKey(key));
        redisTemplate.delete(getKey(key));
        return value;
    }
    private Object getKey (Object key) {
        if (key instanceof PrincipalCollection) {
            return this.keyPrefix + getRedisKeyFromPrincipalIdField((PrincipalCollection)key);
        }
        return (key instanceof String ? (this.keyPrefix + key) : key);
    }
    /**
     * èŽ·å–redis cache key
     */
    private String getRedisKeyFromPrincipalIdField(PrincipalCollection key) {
        Object principalObject = key.getPrimaryPrincipal();
        if (principalObject instanceof String) {
            return principalObject.toString();
        } else {
            Method pincipalIdGetter = this.getPrincipalIdGetter(principalObject);
            return this.getIdObj(principalObject, pincipalIdGetter);
        }
    }
    private Method getPrincipalIdGetter(Object principalObject) {
        Method pincipalIdGetter;
        String principalIdMethodName = this.getPrincipalIdMethodName();
        try {
            pincipalIdGetter = principalObject.getClass().getMethod(principalIdMethodName);
            return pincipalIdGetter;
        } catch (NoSuchMethodException e) {
            throw new SerializationException(e.getMessage(), e);
        }
    }
    private String getIdObj(Object principalObject, Method pincipalIdGetter) {
        try {
            Object idObj = pincipalIdGetter.invoke(principalObject);
            String redisKey = idObj.toString();
            return redisKey;
        } catch (Exception e) {
            throw new SerializationException(e.getMessage(), e);
        }
    }
    private String getPrincipalIdMethodName() {
        return "getId";
    }
}
server/src/main/java/doumeemes/config/shiro/ShiroCacheManager.java
@@ -14,10 +14,10 @@
/**
 * è‡ªå®šä¹‰Shiro CacheManager
 * @author Eva.Caesar Liu
 * @date 2022/04/18 18:12
 * @date 2023/04/17 12:11
 */
@Slf4j
//@Component
@Component
public class ShiroCacheManager implements CacheManager {
    private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap();
server/src/main/java/doumeemes/config/shiro/ShiroConfig.java
@@ -1,28 +1,31 @@
package doumeemes.config.shiro;
import doumeemes.task.ScheduleTool;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.util.ThreadContext;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import javax.servlet.Filter;
import java.util.HashMap;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
/**
 * Shiro配置
 * @author Eva.Caesar Liu
 * @date 2022/04/18 18:12
 * @date 2023/04/17 12:11
 */
//@Configuration
@Configuration
public class ShiroConfig {
    @Value("${cache.session.expire}")
@@ -39,6 +42,20 @@
    @Autowired
    private ShiroRealm shiroRealm;
    @Bean("sessionRedisTemplate")
    public RedisTemplate<Object, Serializable> sessionRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Serializable> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // é»˜è®¤åºåˆ—化方式
        redisTemplate.setDefaultSerializer(new StringRedisSerializer());
        // å€¼åºåˆ—化方式
        ShiroSessionSerializer serializer = new ShiroSessionSerializer();
        redisTemplate.setValueSerializer(serializer);
        redisTemplate.setHashValueSerializer(serializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
@@ -60,7 +77,6 @@
        securityManager.setRealm(shiroRealm);
        securityManager.setSessionManager(this.sessionManager());
        securityManager.setCacheManager(shiroCacheManager);
        ThreadContext.bind(securityManager);
        return securityManager;
    }
@@ -70,26 +86,17 @@
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String, String> map = new LinkedHashMap<>();
        // è·¯å¾„拦截配置
        map.put("/web/user/login", "anon");
        map.put("/public/uploadRichText", "anon");
        map.put("/system/login", "anon");
        map.put("/system/wxLogin", "anon");
        map.put("/system/wxProgramLogin", "anon");
        map.put("/system/wxAccountLogin", "anon");
        map.put("/system/initCompany", "anon");
        map.put("/system/logout", "anon");
        map.put("/common/captcha", "anon");
        map.put("/statistics/**", "anon");
        map.put("/dingding/push", "anon");
//        map.put("/ext/workorderExt/freshStatistics", "anon");
        map.put("/dingding/jsapiTicket", "anon");
        map.put("/dingding/ddLogin", "anon");
        map.put("/dingding/getDingdingCorpId", "anon");
        map.put("/lingyang/login", "anon");
        map.put("/lingyang/loginDemo", "anon");
        map.put("/edgp/**", "anon");
        //放行 scratch æŽ¥å£
        map.put("/web/scratch/**", "anon");
        // - æ”¾è¡Œswagger
        map.put("/doc.html", "anon");
        map.put("/webjars/**", "anon");
        map.put("/template/**", "anon");
        map.put("/swagger-resources/**", "anon");
        map.put("/v2/api-docs/**", "anon");
        // - å…¶ä»–接口统一拦截
server/src/main/java/doumeemes/config/shiro/ShiroCredentialsMatcher.java
@@ -1,5 +1,6 @@
package doumeemes.config.shiro;
import doumeemes.config.shiro.ShiroToken;
import doumeemes.core.utils.Utils;
import doumeemes.dao.system.model.SystemUser;
import doumeemes.service.system.SystemUserService;
@@ -13,11 +14,10 @@
/**
 * Shiro密码比对处理
 * @author Eva.Caesar Liu
 * @date 2022/04/18 18:12
 * @date 2023/04/17 12:11
 */
//@Component
@Component
public class ShiroCredentialsMatcher extends HashedCredentialsMatcher {
    @Lazy
    @Autowired
    private SystemUserService systemUserService;
server/src/main/java/doumeemes/config/shiro/ShiroRealm.java
@@ -4,9 +4,6 @@
import doumeemes.core.exception.BusinessException;
import doumeemes.core.model.LoginUserInfo;
import doumeemes.core.utils.Constants;
import doumeemes.dao.business.model.Company;
import doumeemes.dao.business.model.CompanyUser;
import doumeemes.dao.business.model.Department;
import doumeemes.dao.ext.dto.QueryCompanyUserExtDTO;
import doumeemes.dao.ext.vo.CompanyExtListVO;
import doumeemes.dao.ext.vo.CompanyUserExtListVO;
@@ -15,7 +12,6 @@
import doumeemes.dao.system.model.SystemPermission;
import doumeemes.dao.system.model.SystemRole;
import doumeemes.dao.system.model.SystemUser;
import doumeemes.service.business.CompanyUserService;
import doumeemes.service.ext.CompanyExtService;
import doumeemes.service.ext.CompanyUserExtService;
import doumeemes.service.ext.DepartmentExtService;
@@ -37,14 +33,13 @@
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
 * è‡ªå®šä¹‰Realm,处理认证和权限
 * @author Eva.Caesar Liu
 * @date 2022/04/18 18:12
 * @date 2022/03/15 09:54
 */
//@Component
@Component
public class ShiroRealm extends AuthorizingRealm {
    @Lazy
@@ -70,19 +65,11 @@
    @Lazy
    @Autowired
    private SystemPermissionService systemPermissionService;
    /**
     * é‡å†™supports方法,使 Shiro èƒ½å¤Ÿè¯†åˆ«è‡ªå®šä¹‰çš„ Token
     * @param token
     * @return
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof ShiroToken;
    }
    /**
     * æƒé™å¤„理
     * @author Eva.Caesar Liu
     * @date 2022/04/18 18:12
     * @date 2022/03/15 09:54
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
@@ -97,10 +84,10 @@
    /**
     * è®¤è¯å¤„理
     * @author Eva.Caesar Liu
     * @date 2022/04/18 18:12
     * @date 2022/03/15 09:54
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException,BusinessException {
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // èŽ·å–ç”¨æˆ·å
        ShiroToken authenticationToken =(ShiroToken) token;
        String username = authenticationToken.getPrincipal().toString();
server/src/main/java/doumeemes/config/shiro/ShiroRedisSessionDAO.java
ÎļþÃû´Ó server/src/main/java/doumeemes/config/shiroRedis/ShiroRedisSessionDAO.java ÐÞ¸Ä
@@ -1,4 +1,4 @@
package doumeemes.config.shiroRedis;
package doumeemes.config.shiro;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.SerializationUtils;
server/src/main/java/doumeemes/config/shiro/ShiroSessionDAO.java
@@ -10,16 +10,19 @@
import org.springframework.stereotype.Component;
import java.io.Serializable;
import java.util.*;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
 * è‡ªå®šä¹‰Shiro SessionDAO,将会话信息存入缓存中
 * @author Eva.Caesar Liu
 * @date 2022/04/18 18:12
 * @date 2023/04/17 12:11
 */
//@Data
@Data
@Slf4j
//@Component
@Component
public class ShiroSessionDAO implements SessionDAO {
    private static final String KEY_PREFIX = "shiro:session:";
@@ -27,7 +30,7 @@
    @Autowired
    private ShiroCache shiroCache;
    private int expireTime = 1800;
    private int expireTime = 60 * 60 * 24;
    @Autowired
    private ShiroTokenManager shiroTokenManager;
server/src/main/java/doumeemes/config/shiro/ShiroSessionManager.java
@@ -19,7 +19,7 @@
/**
 * è‡ªå®šä¹‰ä¼šè¯ç®¡ç†å™¨
 * @author Eva.Caesar Liu
 * @date 2022/04/18 18:12
 * @date 2023/04/17 12:11
 */
@Slf4j
public class ShiroSessionManager extends DefaultSessionManager implements WebSessionManager {
server/src/main/java/doumeemes/config/shiro/ShiroSessionSerializer.java
ÎļþÃû´Ó server/src/main/java/doumeemes/config/shiroRedis/ShiroSessionSerializer.java ÐÞ¸Ä
@@ -1,4 +1,4 @@
package doumeemes.config.shiroRedis;
package doumeemes.config.shiro;
import org.apache.commons.lang3.SerializationUtils;
import org.apache.shiro.codec.Base64;
server/src/main/java/doumeemes/config/shiro/ShiroToken.java
@@ -1,34 +1,14 @@
package doumeemes.config.shiro;
import doumeemes.core.model.LoginUserInfo;
import doumeemes.core.utils.Constants;
import doumeemes.dao.business.model.Department;
import doumeemes.dao.ext.dto.QueryCompanyUserExtDTO;
import doumeemes.dao.ext.vo.CompanyUserExtListVO;
import doumeemes.dao.system.model.SystemPermission;
import doumeemes.dao.system.model.SystemRole;
import doumeemes.dao.system.model.SystemUser;
import doumeemes.service.ext.CompanyUserExtService;
import doumeemes.service.system.SystemPermissionService;
import doumeemes.service.system.SystemRoleService;
import doumeemes.service.system.SystemUserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.springframework.stereotype.Component;
import java.util.List;
/**
 * è‡ªå®šä¹‰Token ï¼Œå¤„理认证和权限
 * @author Eva.Caesar Liu
 * @date 2022/04/18 18:12
 */
//@Component
@Component
public class ShiroToken extends UsernamePasswordToken {
    /**
server/src/main/java/doumeemes/config/shiro/ShiroTokenManager.java
@@ -8,9 +8,9 @@
/**
 * é»˜è®¤Token管理器
 * @author Eva.Caesar Liu
 * @date 2022/04/18 18:12
 * @date 2023/04/17 12:11
 */
//@Component
@Component
public class ShiroTokenManager {
    String build() {
server/src/main/java/doumeemes/config/shiroMemory/ShiroAuthFilter.java
ÎļþÃû´Ó server/src/main/java/doumeemes/config/shiroRedis/ShiroAuthFilter.java ÐÞ¸Ä
@@ -1,7 +1,7 @@
package doumeemes.config.shiroRedis;
package doumeemes.config.shiroMemory;
import com.alibaba.fastjson.JSON;
import doumeemes.core.model.ApiResponse;
import com.alibaba.fastjson.JSON;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.springframework.http.HttpStatus;
@@ -12,7 +12,7 @@
/**
 * Shiro认证过滤器,处理未认证情况的响应
 * @author Eva.Caesar Liu
 * @date 2023/04/17 12:11
 * @date 2022/04/18 18:12
 */
public class ShiroAuthFilter extends FormAuthenticationFilter {
server/src/main/java/doumeemes/config/shiroMemory/ShiroCache.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,111 @@
package doumeemes.config.shiroMemory;
import doumeemes.service.proxy.CacheProxy;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
/**
 * Shiro缓存
 * @author Eva.Caesar Liu
 * @date 2022/04/18 18:12
 */
//@Scope(value = "prototype")
@Slf4j
//@Component
public class ShiroCache implements Cache<Object, Serializable> {
    private String keyPrefix = "";
    @Autowired
    private CacheProxy<Object, Serializable> cacheProxy;
    public ShiroCache () {
        log.debug("ShiroCache: new, keyPrefix = [" + keyPrefix + "]");
    }
    public ShiroCache(String keyPrefix) {
        log.debug("ShiroCache: new, keyPrefix = [" + keyPrefix + "]");
        this.keyPrefix = keyPrefix;
    }
    @Override
    public Serializable get(Object key) throws CacheException {
        if (key == null) {
            return null;
        }
        return cacheProxy.get(getKey(key));
    }
    @Override
    public Serializable put(Object key, Serializable value) throws CacheException {
        if (key == null) {
            return null;
        }
        cacheProxy.put(getKey(key), value);
        return value;
    }
    public Serializable put(Object key, Serializable value, int timeout) throws CacheException {
        if (key == null) {
            return null;
        }
        cacheProxy.put(getKey(key), value, timeout);
        return value;
    }
    @Override
    public void clear() throws CacheException {
        Set<Object> keys = this.keys();
        cacheProxy.remove(keys);
    }
    @Override
    public int size() {
        return this.keys().size();
    }
    @Override
    public Set<Object> keys() {
        Set<Object> keys = cacheProxy.keys(keyPrefix + "*");
        if (CollectionUtils.isEmpty(keys)) {
            return Collections.emptySet();
        }
        return keys;
    }
    @Override
    public Collection<Serializable> values() {
        Collection<Serializable> values = new ArrayList<>();
        Set<Object> keys = this.keys();
        if (CollectionUtils.isEmpty(keys)) {
            return values;
        }
        for (Object k : keys) {
            values.add(cacheProxy.get(k));
        }
        return values;
    }
    @Override
    public Serializable remove(Object key) throws CacheException {
        if (key == null) {
            return null;
        }
        Serializable value = this.get(getKey(key));
        cacheProxy.remove(getKey(key));
        return value;
    }
    private Object getKey (Object key) {
        return (key instanceof String ? (this.keyPrefix + key) : key);
    }
}
server/src/main/java/doumeemes/config/shiroMemory/ShiroCacheManager.java
ÎļþÃû´Ó server/src/main/java/doumeemes/config/shiroRedis/ShiroCacheManager.java ÐÞ¸Ä
@@ -1,4 +1,4 @@
package doumeemes.config.shiroRedis;
package doumeemes.config.shiroMemory;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.cache.Cache;
@@ -6,7 +6,6 @@
import org.apache.shiro.cache.CacheManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -14,10 +13,10 @@
/**
 * è‡ªå®šä¹‰Shiro CacheManager
 * @author Eva.Caesar Liu
 * @date 2023/04/17 12:11
 * @date 2022/04/18 18:12
 */
@Slf4j
@Component
//@Component
public class ShiroCacheManager implements CacheManager {
    private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap();
server/src/main/java/doumeemes/config/shiroMemory/ShiroConfig.java
ÎļþÃû´Ó server/src/main/java/doumeemes/config/shiroRedis/ShiroConfig.java ÐÞ¸Ä
@@ -1,30 +1,26 @@
package doumeemes.config.shiroRedis;
package doumeemes.config.shiroMemory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.util.ThreadContext;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import javax.servlet.Filter;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
/**
 * Shiro配置
 * @author Eva.Caesar Liu
 * @date 2023/04/17 12:11
 * @date 2022/04/18 18:12
 */
@Configuration
//@Configuration
public class ShiroConfig {
    @Value("${cache.session.expire}")
@@ -41,20 +37,6 @@
    @Autowired
    private ShiroRealm shiroRealm;
    @Bean("sessionRedisTemplate")
    public RedisTemplate<Object, Serializable> sessionRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Serializable> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // é»˜è®¤åºåˆ—化方式
        redisTemplate.setDefaultSerializer(new StringRedisSerializer());
        // å€¼åºåˆ—化方式
        ShiroSessionSerializer serializer = new ShiroSessionSerializer();
        redisTemplate.setValueSerializer(serializer);
        redisTemplate.setHashValueSerializer(serializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
@@ -76,6 +58,7 @@
        securityManager.setRealm(shiroRealm);
        securityManager.setSessionManager(this.sessionManager());
        securityManager.setCacheManager(shiroCacheManager);
        ThreadContext.bind(securityManager);
        return securityManager;
    }
@@ -85,17 +68,26 @@
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String, String> map = new LinkedHashMap<>();
        // è·¯å¾„拦截配置
        map.put("/web/user/login", "anon");
        map.put("/public/uploadRichText", "anon");
        map.put("/system/login", "anon");
        map.put("/system/wxLogin", "anon");
        map.put("/system/wxProgramLogin", "anon");
        map.put("/system/wxAccountLogin", "anon");
        map.put("/system/initCompany", "anon");
        map.put("/system/logout", "anon");
        map.put("/common/captcha", "anon");
        //放行 scratch æŽ¥å£
        map.put("/web/scratch/**", "anon");
        map.put("/statistics/**", "anon");
        map.put("/dingding/push", "anon");
//        map.put("/ext/workorderExt/freshStatistics", "anon");
        map.put("/dingding/jsapiTicket", "anon");
        map.put("/dingding/ddLogin", "anon");
        map.put("/dingding/getDingdingCorpId", "anon");
        map.put("/lingyang/login", "anon");
        map.put("/lingyang/loginDemo", "anon");
        map.put("/edgp/**", "anon");
        // - æ”¾è¡Œswagger
        map.put("/doc.html", "anon");
        map.put("/webjars/**", "anon");
        map.put("/template/**", "anon");
        map.put("/swagger-resources/**", "anon");
        map.put("/v2/api-docs/**", "anon");
        // - å…¶ä»–接口统一拦截
server/src/main/java/doumeemes/config/shiroMemory/ShiroCredentialsMatcher.java
ÎļþÃû´Ó server/src/main/java/doumeemes/config/shiroRedis/ShiroCredentialsMatcher.java ÐÞ¸Ä
@@ -1,31 +1,29 @@
package doumeemes.config.shiroRedis;
package doumeemes.config.shiroMemory;
import doumeemes.config.shiro.ShiroToken;
import doumeemes.core.utils.Utils;
import doumeemes.dao.system.model.SystemUser;
import doumeemes.service.system.SystemUserService;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
/**
 * Shiro密码比对处理
 * @author Eva.Caesar Liu
 * @date 2023/04/17 12:11
 * @date 2022/04/18 18:12
 */
@Component
//@Component
public class ShiroCredentialsMatcher extends HashedCredentialsMatcher {
    @Lazy
    @Autowired
    private SystemUserService systemUserService;
    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        doumeemes.config.shiro.ShiroToken usernamePasswordToken = (ShiroToken) token;
        ShiroToken usernamePasswordToken = (ShiroToken) token;
        SystemUser queryUserDto = new SystemUser();
        queryUserDto.setUsername(usernamePasswordToken.getUsername());
        queryUserDto.setDeleted(Boolean.FALSE);
server/src/main/java/doumeemes/config/shiroMemory/ShiroRealm.java
ÎļþÃû´Ó server/src/main/java/doumeemes/config/shiroRedis/ShiroRealm.java ÐÞ¸Ä
@@ -1,4 +1,4 @@
package doumeemes.config.shiroRedis;
package doumeemes.config.shiroMemory;
import doumeemes.core.constants.ResponseStatus;
import doumeemes.core.exception.BusinessException;
@@ -19,7 +19,6 @@
import doumeemes.service.system.SystemPermissionService;
import doumeemes.service.system.SystemRoleService;
import doumeemes.service.system.SystemUserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
@@ -30,7 +29,6 @@
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
@@ -38,9 +36,9 @@
/**
 * è‡ªå®šä¹‰Realm,处理认证和权限
 * @author Eva.Caesar Liu
 * @date 2022/03/15 09:54
 * @date 2022/04/18 18:12
 */
@Component
//@Component
public class ShiroRealm extends AuthorizingRealm {
    @Lazy
@@ -66,11 +64,19 @@
    @Lazy
    @Autowired
    private SystemPermissionService systemPermissionService;
    /**
     * é‡å†™supports方法,使 Shiro èƒ½å¤Ÿè¯†åˆ«è‡ªå®šä¹‰çš„ Token
     * @param token
     * @return
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof ShiroToken;
    }
    /**
     * æƒé™å¤„理
     * @author Eva.Caesar Liu
     * @date 2022/03/15 09:54
     * @date 2022/04/18 18:12
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
@@ -85,10 +91,10 @@
    /**
     * è®¤è¯å¤„理
     * @author Eva.Caesar Liu
     * @date 2022/03/15 09:54
     * @date 2022/04/18 18:12
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException,BusinessException {
        // èŽ·å–ç”¨æˆ·å
        ShiroToken authenticationToken =(ShiroToken) token;
        String username = authenticationToken.getPrincipal().toString();
server/src/main/java/doumeemes/config/shiroMemory/ShiroSessionDAO.java
ÎļþÃû´Ó server/src/main/java/doumeemes/config/shiroRedis/ShiroSessionDAO.java ÐÞ¸Ä
@@ -1,28 +1,23 @@
package doumeemes.config.shiroRedis;
package doumeemes.config.shiroMemory;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.SimpleSession;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.*;
/**
 * è‡ªå®šä¹‰Shiro SessionDAO,将会话信息存入缓存中
 * @author Eva.Caesar Liu
 * @date 2023/04/17 12:11
 * @date 2022/04/18 18:12
 */
@Data
//@Data
@Slf4j
@Component
//@Component
public class ShiroSessionDAO implements SessionDAO {
    private static final String KEY_PREFIX = "shiro:session:";
@@ -30,7 +25,7 @@
    @Autowired
    private ShiroCache shiroCache;
    private int expireTime = 60 * 60 * 24;
    private int expireTime = 1800;
    @Autowired
    private ShiroTokenManager shiroTokenManager;
server/src/main/java/doumeemes/config/shiroMemory/ShiroSessionManager.java
ÎļþÃû´Ó server/src/main/java/doumeemes/config/shiroRedis/ShiroSessionManager.java ÐÞ¸Ä
@@ -1,4 +1,4 @@
package doumeemes.config.shiroRedis;
package doumeemes.config.shiroMemory;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.session.Session;
@@ -19,7 +19,7 @@
/**
 * è‡ªå®šä¹‰ä¼šè¯ç®¡ç†å™¨
 * @author Eva.Caesar Liu
 * @date 2023/04/17 12:11
 * @date 2022/04/18 18:12
 */
@Slf4j
public class ShiroSessionManager extends DefaultSessionManager implements WebSessionManager {
server/src/main/java/doumeemes/config/shiroMemory/ShiroToken.java
ÎļþÃû´Ó server/src/main/java/doumeemes/config/shiroRedis/ShiroToken.java ÐÞ¸Ä
@@ -1,14 +1,13 @@
package doumeemes.config.shiroRedis;
package doumeemes.config.shiroMemory;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.springframework.stereotype.Component;
import org.apache.shiro.authc.*;
/**
 * è‡ªå®šä¹‰Token ï¼Œå¤„理认证和权限
 * @author Eva.Caesar Liu
 * @date 2022/04/18 18:12
 */
@Component
//@Component
public class ShiroToken extends UsernamePasswordToken {
    /**
server/src/main/java/doumeemes/config/shiroMemory/ShiroTokenManager.java
ÎļþÃû´Ó server/src/main/java/doumeemes/config/shiroRedis/ShiroTokenManager.java ÐÞ¸Ä
@@ -1,16 +1,15 @@
package doumeemes.config.shiroRedis;
package doumeemes.config.shiroMemory;
import doumeemes.core.exception.UnSafeSessionException;
import org.springframework.stereotype.Component;
import java.util.UUID;
/**
 * é»˜è®¤Token管理器
 * @author Eva.Caesar Liu
 * @date 2023/04/17 12:11
 * @date 2022/04/18 18:12
 */
@Component
//@Component
public class ShiroTokenManager {
    String build() {
server/src/main/java/doumeemes/config/shiroRedis/ShiroCache.java
ÎļþÒÑɾ³ý
server/src/main/java/doumeemes/service/system/impl/SystemLoginServiceImpl.java
@@ -1,8 +1,6 @@
package doumeemes.service.system.impl;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.iflytek.antelope.other.client.dto.resp.UserDTO;
import doumeemes.biz.system.SystemDictDataBiz;
import doumeemes.config.shiro.ShiroToken;
@@ -14,9 +12,7 @@
import doumeemes.core.utils.dingding.DingDingUtil;
import doumeemes.core.utils.dingding.LingyangUtil;
import doumeemes.core.utils.edpg.EdgpServerUtil;
import doumeemes.core.utils.edpg.EdgpUtil;
import doumeemes.core.utils.edpg.bean.AppUserInfoModel;
import doumeemes.dao.business.dto.CompanyInitDataDTO;
import doumeemes.dao.business.model.Company;
import doumeemes.dao.business.model.CompanyUser;
import doumeemes.dao.ext.CompanyExtMapper;
server/src/main/java/doumeemes/service/system/impl/WxLoginServiceImpl.java
@@ -19,18 +19,13 @@
import doumeemes.dao.ext.CompanyExtMapper;
import doumeemes.dao.ext.CompanyUserExtMapper;
import doumeemes.dao.ext.DepartmentExtMapper;
import doumeemes.dao.ext.dto.QueryCompanyUserExtDTO;
import doumeemes.dao.ext.dto.WxLoginDTO;
import doumeemes.dao.ext.dto.WxLoginOutDTO;
import doumeemes.dao.ext.vo.CompanyUserExtListVO;
import doumeemes.dao.ext.vo.WxLoginVO;
import doumeemes.dao.system.SystemUserMapper;
import doumeemes.dao.system.dto.LoginDTO;
import doumeemes.dao.system.model.SystemLoginLog;
import doumeemes.dao.system.model.SystemUser;
import doumeemes.service.common.CaptchaService;
import doumeemes.service.ext.CompanyExtService;
import doumeemes.service.ext.CompanyUserExtService;
import doumeemes.service.system.SystemLoginLogService;
import doumeemes.service.system.WxLoginService;
import lombok.extern.slf4j.Slf4j;
@@ -41,7 +36,6 @@
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;