mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-04 12:18:42 +08:00 
			
		
		
		
	1.【修复】定时任务刷新本地缓存时,无租户上线文,导致查询报错
2. member 模块,统一使用 member 前缀 3. 修改 Spring Security logout 配置,支持多用户类型的退出
This commit is contained in:
		@@ -1,7 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "local": {
 | 
			
		||||
    "baseUrl": "http://127.0.0.1:48080/api",
 | 
			
		||||
    "userServerUrl": "http://127.0.0.1:28080/api",
 | 
			
		||||
    "token": "test1",
 | 
			
		||||
 | 
			
		||||
    "userApi": "http://127.0.0.1:48080/app-api",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 | 
			
		||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 | 
			
		||||
import cn.iocoder.yudao.adminserver.modules.system.controller.dept.vo.dept.SysDeptListReqVO;
 | 
			
		||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.dept.SysDeptDO;
 | 
			
		||||
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
 | 
			
		||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 | 
			
		||||
import org.apache.ibatis.annotations.Mapper;
 | 
			
		||||
 | 
			
		||||
@@ -28,6 +29,7 @@ public interface SysDeptMapper extends BaseMapperX<SysDeptDO> {
 | 
			
		||||
        return selectCount(SysDeptDO::getParentId, parentId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @InterceptorIgnore(tenantLine = "on") // 该方法忽略多租户。原因:该方法被异步 task 调用,此时获取不到租户编号
 | 
			
		||||
    default boolean selectExistsByUpdateTimeAfter(Date maxUpdateTime) {
 | 
			
		||||
        return selectOne(new LambdaQueryWrapper<SysDeptDO>().select(SysDeptDO::getId)
 | 
			
		||||
                .gt(SysDeptDO::getUpdateTime, maxUpdateTime).last(SqlConstants.LIMIT1)) != null;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
package cn.iocoder.yudao.framework.security.config;
 | 
			
		||||
 | 
			
		||||
import cn.hutool.core.util.StrUtil;
 | 
			
		||||
import cn.iocoder.yudao.framework.security.core.authentication.MultiUserDetailsAuthenticationProvider;
 | 
			
		||||
import cn.iocoder.yudao.framework.security.core.filter.JWTAuthenticationTokenFilter;
 | 
			
		||||
import cn.iocoder.yudao.framework.security.core.service.SecurityAuthFrameworkService;
 | 
			
		||||
@@ -21,8 +22,10 @@ import org.springframework.security.web.AuthenticationEntryPoint;
 | 
			
		||||
import org.springframework.security.web.access.AccessDeniedHandler;
 | 
			
		||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
 | 
			
		||||
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
 | 
			
		||||
import org.springframework.security.web.util.matcher.RequestMatcher;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 自定义的 Spring Security 配置适配器实现
 | 
			
		||||
@@ -106,6 +109,7 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void configure(HttpSecurity httpSecurity) throws Exception {
 | 
			
		||||
        // 登出
 | 
			
		||||
        httpSecurity
 | 
			
		||||
                // 开启跨域
 | 
			
		||||
                .cors().and()
 | 
			
		||||
@@ -117,7 +121,9 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap
 | 
			
		||||
                // 一堆自定义的 Spring Security 处理器
 | 
			
		||||
                .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint)
 | 
			
		||||
                    .accessDeniedHandler(accessDeniedHandler).and()
 | 
			
		||||
                .logout().logoutUrl(buildAdminApi("/logout")).logoutSuccessHandler(logoutSuccessHandler); // 登出
 | 
			
		||||
                // 登出地址的配置
 | 
			
		||||
                .logout().logoutSuccessHandler(logoutSuccessHandler).logoutRequestMatcher(request -> // 匹配多种用户类型的登出
 | 
			
		||||
                        StrUtil.equalsAny(request.getRequestURI(), buildAdminApi("/logout"), buildAppApi("/member/logout")));
 | 
			
		||||
 | 
			
		||||
        // 设置每个请求的权限 ①:全局共享规则
 | 
			
		||||
        httpSecurity.authorizeRequests()
 | 
			
		||||
 
 | 
			
		||||
@@ -41,6 +41,19 @@ public class SecurityFrameworkUtils {
 | 
			
		||||
        return authorization.substring(index + 7).trim();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获得当前认证信息
 | 
			
		||||
     *
 | 
			
		||||
     * @return 认证信息
 | 
			
		||||
     */
 | 
			
		||||
    public static Authentication getAuthentication() {
 | 
			
		||||
        SecurityContext context = SecurityContextHolder.getContext();
 | 
			
		||||
        if (context == null) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        return context.getAuthentication();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取当前用户
 | 
			
		||||
     *
 | 
			
		||||
@@ -48,11 +61,7 @@ public class SecurityFrameworkUtils {
 | 
			
		||||
     */
 | 
			
		||||
    @Nullable
 | 
			
		||||
    public static LoginUser getLoginUser() {
 | 
			
		||||
        SecurityContext context = SecurityContextHolder.getContext();
 | 
			
		||||
        if (context == null) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        Authentication authentication = context.getAuthentication();
 | 
			
		||||
        Authentication authentication = getAuthentication();
 | 
			
		||||
        if (authentication == null) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
@@ -88,16 +97,22 @@ public class SecurityFrameworkUtils {
 | 
			
		||||
     * @param request 请求
 | 
			
		||||
     */
 | 
			
		||||
    public static void setLoginUser(LoginUser loginUser, HttpServletRequest request) {
 | 
			
		||||
        // 创建 UsernamePasswordAuthenticationToken 对象
 | 
			
		||||
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
 | 
			
		||||
                loginUser, null, loginUser.getAuthorities());
 | 
			
		||||
        authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
 | 
			
		||||
        // 设置到上下文
 | 
			
		||||
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
 | 
			
		||||
        // 创建 Authentication,并设置到上下文
 | 
			
		||||
        Authentication authentication = buildAuthentication(loginUser, request);
 | 
			
		||||
        SecurityContextHolder.getContext().setAuthentication(authentication);
 | 
			
		||||
 | 
			
		||||
        // 额外设置到 request 中,用于 ApiAccessLogFilter 可以获取到用户编号;
 | 
			
		||||
        // 原因是,Spring Security 的 Filter 在 ApiAccessLogFilter 后面,在它记录访问日志时,线上上下文已经没有用户编号等信息
 | 
			
		||||
        WebFrameworkUtils.setLoginUserId(request, loginUser.getId());
 | 
			
		||||
        WebFrameworkUtils.setLoginUserType(request, loginUser.getUserType());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static Authentication buildAuthentication(LoginUser loginUser, HttpServletRequest request) {
 | 
			
		||||
        // 创建 UsernamePasswordAuthenticationToken 对象
 | 
			
		||||
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
 | 
			
		||||
                loginUser, null, loginUser.getAuthorities());
 | 
			
		||||
        authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
 | 
			
		||||
        return authenticationToken;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -10,17 +10,11 @@ import cn.iocoder.yudao.coreservice.modules.bpm.api.group.BpmUserGroupServiceApi
 | 
			
		||||
import cn.iocoder.yudao.coreservice.modules.system.service.dept.SysDeptCoreService;
 | 
			
		||||
import cn.iocoder.yudao.coreservice.modules.system.service.permission.SysPermissionCoreService;
 | 
			
		||||
import cn.iocoder.yudao.coreservice.modules.system.service.user.SysUserCoreService;
 | 
			
		||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmUserGroupService;
 | 
			
		||||
import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysDeptService;
 | 
			
		||||
import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService;
 | 
			
		||||
import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService;
 | 
			
		||||
import org.activiti.api.runtime.shared.identity.UserGroupManager;
 | 
			
		||||
import org.activiti.core.common.spring.identity.ActivitiUserGroupManagerImpl;
 | 
			
		||||
import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer;
 | 
			
		||||
import org.springframework.context.ApplicationEventPublisher;
 | 
			
		||||
import org.springframework.context.annotation.Bean;
 | 
			
		||||
import org.springframework.context.annotation.Configuration;
 | 
			
		||||
import org.springframework.security.core.userdetails.UserDetailsService;
 | 
			
		||||
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
### 请求 /login 接口 => 成功
 | 
			
		||||
POST {{userApi}}/login
 | 
			
		||||
POST {{userApi}}/member/login
 | 
			
		||||
Content-Type: application/json
 | 
			
		||||
tenant-id: {{userTenentId}}
 | 
			
		||||
 | 
			
		||||
@@ -9,8 +9,9 @@ tenant-id: {{userTenentId}}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
### 请求 /send-sms-code 接口 => 成功
 | 
			
		||||
POST {{userServerUrl}}/send-sms-code
 | 
			
		||||
POST {{userApi}}/member/send-sms-code
 | 
			
		||||
Content-Type: application/json
 | 
			
		||||
tenant-id: {{userTenentId}}
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
  "mobile": "15601691399",
 | 
			
		||||
@@ -18,8 +19,9 @@ Content-Type: application/json
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
### 请求 /sms-login 接口 => 成功
 | 
			
		||||
POST {{userServerUrl}}/sms-login
 | 
			
		||||
POST {{userApi}}/member/sms-login
 | 
			
		||||
Content-Type: application/json
 | 
			
		||||
tenant-id: {{userTenentId}}
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
  "mobile": "15601691301",
 | 
			
		||||
@@ -27,6 +29,7 @@ Content-Type: application/json
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
### 请求 /logout 接口 => 成功
 | 
			
		||||
POST {{userServerUrl}}/logout
 | 
			
		||||
POST {{userApi}}/member/logout
 | 
			
		||||
Content-Type: application/json
 | 
			
		||||
Authorization: Bearer c1b76bdaf2c146c581caa4d7fd81ee66
 | 
			
		||||
tenant-id: {{userTenentId}}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
 | 
			
		||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 | 
			
		||||
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
 | 
			
		||||
import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
 | 
			
		||||
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
 | 
			
		||||
import cn.iocoder.yudao.module.member.controller.app.auth.vo.*;
 | 
			
		||||
import cn.iocoder.yudao.module.member.service.auth.AuthService;
 | 
			
		||||
import cn.iocoder.yudao.module.member.service.sms.SysSmsCodeService;
 | 
			
		||||
@@ -13,6 +14,7 @@ import io.swagger.annotations.ApiImplicitParam;
 | 
			
		||||
import io.swagger.annotations.ApiImplicitParams;
 | 
			
		||||
import io.swagger.annotations.ApiOperation;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
 | 
			
		||||
import org.springframework.validation.annotation.Validated;
 | 
			
		||||
import org.springframework.web.bind.annotation.*;
 | 
			
		||||
 | 
			
		||||
@@ -26,7 +28,7 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti
 | 
			
		||||
 | 
			
		||||
@Api(tags = "APP 端 - 认证")
 | 
			
		||||
@RestController
 | 
			
		||||
@RequestMapping("/")
 | 
			
		||||
@RequestMapping("/member/")
 | 
			
		||||
@Validated
 | 
			
		||||
@Slf4j
 | 
			
		||||
public class AppAuthController {
 | 
			
		||||
@@ -39,6 +41,9 @@ public class AppAuthController {
 | 
			
		||||
    @Resource
 | 
			
		||||
    private SysSocialCoreService socialService;
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private LogoutSuccessHandler logoutSuccessHandler;
 | 
			
		||||
 | 
			
		||||
    @PostMapping("/login")
 | 
			
		||||
    @ApiOperation("使用手机 + 密码登录")
 | 
			
		||||
    @OperateLog(enable = false) // 避免 Post 请求被记录操作日志
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package cn.iocoder.yudao.userserver.modules.weixin.controller.mp;
 | 
			
		||||
package cn.iocoder.yudao.module.member.controller.app.weixin;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 | 
			
		||||
import io.swagger.annotations.Api;
 | 
			
		||||
@@ -19,10 +19,10 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 | 
			
		||||
 | 
			
		||||
@Api(tags = "微信公众号")
 | 
			
		||||
@RestController
 | 
			
		||||
@RequestMapping("/wx/mp")
 | 
			
		||||
@RequestMapping("/member/wx-mp")
 | 
			
		||||
@Validated
 | 
			
		||||
@Slf4j
 | 
			
		||||
public class WxMpController {
 | 
			
		||||
public class AppWxMpController {
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private WxMpService mpService;
 | 
			
		||||
@@ -16,7 +16,7 @@ import java.util.Date;
 | 
			
		||||
 *
 | 
			
		||||
 * @author 芋道源码
 | 
			
		||||
 */
 | 
			
		||||
@TableName(value = "mbr_user", autoResultMap = true)
 | 
			
		||||
@TableName(value = "member_user", autoResultMap = true)
 | 
			
		||||
@Data
 | 
			
		||||
@EqualsAndHashCode(callSuper = true)
 | 
			
		||||
@Builder
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,6 @@
 | 
			
		||||
 * 2. redis:Redis 的 CRUD 操作
 | 
			
		||||
 * 3. mysql:MySQL 的 CRUD 操作
 | 
			
		||||
 *
 | 
			
		||||
 * 其中,MySQL 的表以 mbr_ 作为前缀
 | 
			
		||||
 * 其中,MySQL 的表以 member_ 作为前缀
 | 
			
		||||
 */
 | 
			
		||||
package cn.iocoder.yudao.module.member.dal;
 | 
			
		||||
 
 | 
			
		||||
@@ -1 +1,8 @@
 | 
			
		||||
/**
 | 
			
		||||
 * member 模块,我们放会员业务。
 | 
			
		||||
 * 例如说:会员中心等等
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Controller URL:以 /member/ 开头,避免和其它 Module 冲突
 | 
			
		||||
 * 2. DataObject 表名:以 member_ 开头,方便在数据库中区分
 | 
			
		||||
 */
 | 
			
		||||
package cn.iocoder.yudao.module.member;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,2 +1,2 @@
 | 
			
		||||
-- mbr 开头的 DB
 | 
			
		||||
DELETE FROM "mbr_user";
 | 
			
		||||
DELETE FROM "member_user";
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
-- mbr 开头的 DB
 | 
			
		||||
CREATE TABLE IF NOT EXISTS "mbr_user"  (
 | 
			
		||||
CREATE TABLE IF NOT EXISTS "member_user"  (
 | 
			
		||||
    "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '编号',
 | 
			
		||||
    "nickname" varchar(30)  NOT NULL DEFAULT '' COMMENT '用户昵称',
 | 
			
		||||
    "avatar" varchar(255)  NOT NULL DEFAULT '' COMMENT '头像',
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +0,0 @@
 | 
			
		||||
package cn.iocoder.yudao.userserver;
 | 
			
		||||
 | 
			
		||||
import org.springframework.boot.SpringApplication;
 | 
			
		||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
 | 
			
		||||
 | 
			
		||||
@SuppressWarnings("SpringComponentScan") // 忽略 IDEA 无法识别 ${yudao.info.base-package} 和 ${yudao.core-service.base-package}
 | 
			
		||||
@SpringBootApplication(scanBasePackages = {"${yudao.info.base-package}", "${yudao.core-service.base-package}"})
 | 
			
		||||
public class UserServerApplication {
 | 
			
		||||
 | 
			
		||||
    public static void main(String[] args) {
 | 
			
		||||
        SpringApplication.run(UserServerApplication.class, args);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,7 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * weixin 包下,我们放通用业务,支撑上层的核心业务。
 | 
			
		||||
 * 例如说:用户、部门、权限、数据字典等等
 | 
			
		||||
 *
 | 
			
		||||
 * 缩写:wx
 | 
			
		||||
 */
 | 
			
		||||
package cn.iocoder.yudao.userserver.modules.weixin;
 | 
			
		||||
@@ -37,8 +37,6 @@ mybatis-plus:
 | 
			
		||||
  mapper-locations: classpath*:mapper/*.xml
 | 
			
		||||
  type-aliases-package: ${yudao.info.base-package}.modules.*.dal.dataobject, ${yudao.core-service.base-package}.modules.*.dal.dataobject
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
--- #################### 芋道相关配置 ####################
 | 
			
		||||
 | 
			
		||||
yudao:
 | 
			
		||||
@@ -67,5 +65,4 @@ yudao:
 | 
			
		||||
      - cn.iocoder.yudao.userserver.modules.member.enums.MbrErrorCodeConstants
 | 
			
		||||
      - cn.iocoder.yudao.userserver.modules.system.enums.SysErrorCodeConstants
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
debug: false
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user