mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-04 04:08:43 +08:00 
			
		
		
		
	去除 Spring Security 的 logout handler,使用自己定义的 logout 接口
This commit is contained in:
		@@ -1,9 +1,12 @@
 | 
			
		||||
package cn.iocoder.yudao.module.system.controller.admin.auth;
 | 
			
		||||
 | 
			
		||||
import cn.hutool.core.util.StrUtil;
 | 
			
		||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 | 
			
		||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 | 
			
		||||
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
 | 
			
		||||
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
 | 
			
		||||
import cn.iocoder.yudao.framework.security.config.SecurityProperties;
 | 
			
		||||
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
 | 
			
		||||
import cn.iocoder.yudao.module.system.controller.admin.auth.vo.auth.*;
 | 
			
		||||
import cn.iocoder.yudao.module.system.convert.auth.AuthConvert;
 | 
			
		||||
import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
 | 
			
		||||
@@ -24,6 +27,7 @@ import org.springframework.validation.annotation.Validated;
 | 
			
		||||
import org.springframework.web.bind.annotation.*;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import javax.validation.Valid;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
@@ -52,15 +56,28 @@ public class AuthController {
 | 
			
		||||
    @Resource
 | 
			
		||||
    private SocialUserService socialUserService;
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private SecurityProperties securityProperties;
 | 
			
		||||
 | 
			
		||||
    @PostMapping("/login")
 | 
			
		||||
    @ApiOperation("使用账号密码登录")
 | 
			
		||||
    @OperateLog(enable = false) // 避免 Post 请求被记录操作日志
 | 
			
		||||
    public CommonResult<AuthLoginRespVO> login(@RequestBody @Valid AuthLoginReqVO reqVO) {
 | 
			
		||||
        String token = authService.login(reqVO, getClientIP(), getUserAgent());
 | 
			
		||||
        // 返回结果
 | 
			
		||||
        return success(AuthLoginRespVO.builder().token(token).build());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @PostMapping("/logout")
 | 
			
		||||
    @ApiOperation("登出系统")
 | 
			
		||||
    @OperateLog(enable = false) // 避免 Post 请求被记录操作日志
 | 
			
		||||
    public CommonResult<Boolean> logout(HttpServletRequest request) {
 | 
			
		||||
        String token = SecurityFrameworkUtils.obtainAuthorization(request, securityProperties.getTokenHeader());
 | 
			
		||||
        if (StrUtil.isNotBlank(token)) {
 | 
			
		||||
            authService.logout(token);
 | 
			
		||||
        }
 | 
			
		||||
        return success(true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @GetMapping("/get-permission-info")
 | 
			
		||||
    @ApiOperation("获取登录用户的权限信息")
 | 
			
		||||
    public CommonResult<AuthPermissionInfoRespVO> getPermissionInfo() {
 | 
			
		||||
@@ -130,7 +147,6 @@ public class AuthController {
 | 
			
		||||
    @OperateLog(enable = false) // 避免 Post 请求被记录操作日志
 | 
			
		||||
    public CommonResult<AuthLoginRespVO> socialQuickLogin(@RequestBody @Valid AuthSocialQuickLoginReqVO reqVO) {
 | 
			
		||||
        String token = authService.socialQuickLogin(reqVO, getClientIP(), getUserAgent());
 | 
			
		||||
        // 返回结果
 | 
			
		||||
        return success(AuthLoginRespVO.builder().token(token).build());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -139,7 +155,6 @@ public class AuthController {
 | 
			
		||||
    @OperateLog(enable = false) // 避免 Post 请求被记录操作日志
 | 
			
		||||
    public CommonResult<AuthLoginRespVO> socialBindLogin(@RequestBody @Valid AuthSocialBindLoginReqVO reqVO) {
 | 
			
		||||
        String token = authService.socialBindLogin(reqVO, getClientIP(), getUserAgent());
 | 
			
		||||
        // 返回结果
 | 
			
		||||
        return success(AuthLoginRespVO.builder().token(token).build());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,55 @@
 | 
			
		||||
package cn.iocoder.yudao.module.system.dal.dataobject.auth;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
 | 
			
		||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 | 
			
		||||
import com.baomidou.mybatisplus.annotation.TableName;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.EqualsAndHashCode;
 | 
			
		||||
import lombok.experimental.Accessors;
 | 
			
		||||
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * OAuth2 访问令牌
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
@TableName("system_oauth2_access_token")
 | 
			
		||||
@Data
 | 
			
		||||
@EqualsAndHashCode(callSuper = true)
 | 
			
		||||
@Accessors(chain = true)
 | 
			
		||||
public class OAuth2AccessTokenDO extends BaseDO {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 编号,数据库字典
 | 
			
		||||
     */
 | 
			
		||||
    private Long id;
 | 
			
		||||
    /**
 | 
			
		||||
     * 访问令牌
 | 
			
		||||
     */
 | 
			
		||||
    private String accessToken;
 | 
			
		||||
    /**
 | 
			
		||||
     * 用户编号
 | 
			
		||||
     */
 | 
			
		||||
    private Long userId;
 | 
			
		||||
    /**
 | 
			
		||||
     * 用户类型
 | 
			
		||||
     *
 | 
			
		||||
     * 枚举 {@link UserTypeEnum}
 | 
			
		||||
     */
 | 
			
		||||
    private Integer userType;
 | 
			
		||||
    /**
 | 
			
		||||
     * 刷新令牌
 | 
			
		||||
     *
 | 
			
		||||
     * 关联 {@link OAuth2RefreshTokenDO#getRefreshToken()}
 | 
			
		||||
     */
 | 
			
		||||
    private String refreshToken;
 | 
			
		||||
    /**
 | 
			
		||||
     * 过期时间
 | 
			
		||||
     */
 | 
			
		||||
    private Date expiresTime;
 | 
			
		||||
    /**
 | 
			
		||||
     * 创建 IP
 | 
			
		||||
     */
 | 
			
		||||
    private String createIp;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,49 @@
 | 
			
		||||
package cn.iocoder.yudao.module.system.dal.dataobject.auth;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
 | 
			
		||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 | 
			
		||||
import com.baomidou.mybatisplus.annotation.TableName;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.EqualsAndHashCode;
 | 
			
		||||
import lombok.experimental.Accessors;
 | 
			
		||||
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * OAuth2 刷新令牌
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
@TableName("system_oauth2_refresh_token")
 | 
			
		||||
@Data
 | 
			
		||||
@EqualsAndHashCode(callSuper = true)
 | 
			
		||||
@Accessors(chain = true)
 | 
			
		||||
public class OAuth2RefreshTokenDO extends BaseDO {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 编号,数据库字典
 | 
			
		||||
     */
 | 
			
		||||
    private Long id;
 | 
			
		||||
    /**
 | 
			
		||||
     * 刷新令牌
 | 
			
		||||
     */
 | 
			
		||||
    private String refreshToken;
 | 
			
		||||
    /**
 | 
			
		||||
     * 用户编号
 | 
			
		||||
     */
 | 
			
		||||
    private Integer userId;
 | 
			
		||||
    /**
 | 
			
		||||
     * 用户类型
 | 
			
		||||
     *
 | 
			
		||||
     * 枚举 {@link UserTypeEnum}
 | 
			
		||||
     */
 | 
			
		||||
    private Integer userType;
 | 
			
		||||
    /**
 | 
			
		||||
     * 过期时间
 | 
			
		||||
     */
 | 
			
		||||
    private Date expiresTime;
 | 
			
		||||
    /**
 | 
			
		||||
     * 创建 IP
 | 
			
		||||
     */
 | 
			
		||||
    private String createIp;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -20,6 +20,7 @@ public class SecurityConfiguration {
 | 
			
		||||
            public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) {
 | 
			
		||||
                // 登录的接口
 | 
			
		||||
                registry.antMatchers(buildAdminApi("/system/auth/login")).permitAll();
 | 
			
		||||
                registry.antMatchers(buildAdminApi("/system/auth/logout")).permitAll();
 | 
			
		||||
                // 社交登陆的接口
 | 
			
		||||
                registry.antMatchers(buildAdminApi("/system/auth/social-auth-redirect")).permitAll();
 | 
			
		||||
                registry.antMatchers(buildAdminApi("/system/auth/social-quick-login")).permitAll();
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,18 @@
 | 
			
		||||
package cn.iocoder.yudao.module.system.service.auth;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * OAuth2.0 Service 接口
 | 
			
		||||
 *
 | 
			
		||||
 * @author 芋道源码
 | 
			
		||||
 */
 | 
			
		||||
public interface OAuth2Service {
 | 
			
		||||
 | 
			
		||||
//    OAuth2AccessTokenDO createAccessToken(Long userId, Integer userType, String createIp);
 | 
			
		||||
//
 | 
			
		||||
//    OAuth2AccessTokenRespDTO checkAccessToken(String accessToken);
 | 
			
		||||
//
 | 
			
		||||
//    OAuth2AccessTokenRespDTO refreshAccessToken(OAuth2RefreshAccessTokenReqDTO refreshAccessTokenDTO);
 | 
			
		||||
//
 | 
			
		||||
//    void removeToken(OAuth2RemoveTokenByUserReqDTO removeTokenDTO);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,143 @@
 | 
			
		||||
package cn.iocoder.yudao.module.system.service.auth;
 | 
			
		||||
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * OAuth2.0 Service 实现类
 | 
			
		||||
 *
 | 
			
		||||
 * @author 芋道源码
 | 
			
		||||
 */
 | 
			
		||||
@Service
 | 
			
		||||
public class OAuth2ServiceImpl implements OAuth2Service {
 | 
			
		||||
 | 
			
		||||
//    @Autowired
 | 
			
		||||
//    private SystemBizProperties systemBizProperties;
 | 
			
		||||
//
 | 
			
		||||
//    @Autowired
 | 
			
		||||
//    private OAuth2AccessTokenMapper oauth2AccessTokenMapper;
 | 
			
		||||
//    @Autowired
 | 
			
		||||
//    private OAuth2RefreshTokenMapper oauth2RefreshTokenMapper;
 | 
			
		||||
//
 | 
			
		||||
//    @Autowired
 | 
			
		||||
//    private OAuth2AccessTokenRedisDAO oauth2AccessTokenRedisDAO;
 | 
			
		||||
//
 | 
			
		||||
//    @Override
 | 
			
		||||
//    @Transactional
 | 
			
		||||
//    public OAuth2AccessTokenRespDTO createAccessToken(OAuth2CreateAccessTokenReqDTO createAccessTokenDTO) {
 | 
			
		||||
//        // 创建刷新令牌 + 访问令牌
 | 
			
		||||
//        OAuth2RefreshTokenDO refreshTokenDO = createOAuth2RefreshToken(createAccessTokenDTO.getUserId(),
 | 
			
		||||
//                createAccessTokenDTO.getUserType(), createAccessTokenDTO.getCreateIp());
 | 
			
		||||
//        OAuth2AccessTokenDO accessTokenDO = createOAuth2AccessToken(refreshTokenDO, createAccessTokenDTO.getCreateIp());
 | 
			
		||||
//        // 返回访问令牌
 | 
			
		||||
//        return OAuth2Convert.INSTANCE.convert(accessTokenDO);
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    @Override
 | 
			
		||||
//    @Transactional
 | 
			
		||||
//    public OAuth2AccessTokenRespDTO checkAccessToken(String accessToken) {
 | 
			
		||||
//        OAuth2AccessTokenDO accessTokenDO = this.getOAuth2AccessToken(accessToken);
 | 
			
		||||
//        if (accessTokenDO == null) { // 不存在
 | 
			
		||||
//            throw ServiceExceptionUtil.exception(OAUTH2_ACCESS_TOKEN_NOT_FOUND);
 | 
			
		||||
//        }
 | 
			
		||||
//        if (accessTokenDO.getExpiresTime().getTime() < System.currentTimeMillis()) { // 已过期
 | 
			
		||||
//            throw ServiceExceptionUtil.exception(OAUTH2_ACCESS_TOKEN_TOKEN_EXPIRED);
 | 
			
		||||
//        }
 | 
			
		||||
//        // 返回访问令牌
 | 
			
		||||
//        return OAuth2Convert.INSTANCE.convert(accessTokenDO);
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    @Override
 | 
			
		||||
//    @Transactional
 | 
			
		||||
//    public OAuth2AccessTokenRespDTO refreshAccessToken(OAuth2RefreshAccessTokenReqDTO refreshAccessTokenDTO) {
 | 
			
		||||
//        OAuth2RefreshTokenDO refreshTokenDO = oauth2RefreshTokenMapper.selectById(refreshAccessTokenDTO.getRefreshToken());
 | 
			
		||||
//        // 校验刷新令牌是否合法
 | 
			
		||||
//        if (refreshTokenDO == null) { // 不存在
 | 
			
		||||
//            throw ServiceExceptionUtil.exception(OAUTH2_REFRESH_TOKEN_NOT_FOUND);
 | 
			
		||||
//        }
 | 
			
		||||
//        if (refreshTokenDO.getExpiresTime().getTime() < System.currentTimeMillis()) { // 已过期
 | 
			
		||||
//            throw ServiceExceptionUtil.exception(OAUTH_REFRESH_TOKEN_EXPIRED);
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        // 标记 refreshToken 对应的 accessToken 都不合法
 | 
			
		||||
//        // 这块的实现,参考了 Spring Security OAuth2 的代码
 | 
			
		||||
//        List<OAuth2AccessTokenDO> accessTokenDOs = oauth2AccessTokenMapper.selectListByRefreshToken(refreshAccessTokenDTO.getRefreshToken());
 | 
			
		||||
//        accessTokenDOs.forEach(accessTokenDO -> deleteOAuth2AccessToken(accessTokenDO.getId()));
 | 
			
		||||
//
 | 
			
		||||
//        // 创建访问令牌
 | 
			
		||||
//        OAuth2AccessTokenDO oauth2AccessTokenDO = createOAuth2AccessToken(refreshTokenDO, refreshAccessTokenDTO.getCreateIp());
 | 
			
		||||
//        // 返回访问令牌
 | 
			
		||||
//        return OAuth2Convert.INSTANCE.convert(oauth2AccessTokenDO);
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    @Override
 | 
			
		||||
//    @Transactional
 | 
			
		||||
//    public void removeToken(OAuth2RemoveTokenByUserReqDTO removeTokenDTO) {
 | 
			
		||||
//        // 删除 Access Token
 | 
			
		||||
//        OAuth2AccessTokenDO accessTokenDO = oauth2AccessTokenMapper.selectByUserIdAndUserType(
 | 
			
		||||
//                removeTokenDTO.getUserId(), removeTokenDTO.getUserType());
 | 
			
		||||
//        if (accessTokenDO != null) {
 | 
			
		||||
//            this.deleteOAuth2AccessToken(accessTokenDO.getId());
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        // 删除 Refresh Token
 | 
			
		||||
//        oauth2RefreshTokenMapper.deleteByUserIdAndUserType(removeTokenDTO.getUserId(), removeTokenDTO.getUserType());
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    private OAuth2AccessTokenDO createOAuth2AccessToken(OAuth2RefreshTokenDO refreshTokenDO, String createIp) {
 | 
			
		||||
//        OAuth2AccessTokenDO accessToken = new OAuth2AccessTokenDO()
 | 
			
		||||
//                .setId(generateAccessToken())
 | 
			
		||||
//                .setUserId(refreshTokenDO.getUserId()).setUserType(refreshTokenDO.getUserType())
 | 
			
		||||
//                .setRefreshToken(refreshTokenDO.getId())
 | 
			
		||||
//                .setExpiresTime(new Date(System.currentTimeMillis() + systemBizProperties.getAccessTokenExpireTimeMillis()))
 | 
			
		||||
//                .setCreateIp(createIp);
 | 
			
		||||
//        oauth2AccessTokenMapper.insert(accessToken);
 | 
			
		||||
//        return accessToken;
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    private OAuth2RefreshTokenDO createOAuth2RefreshToken(Integer userId, Integer userType, String createIp) {
 | 
			
		||||
//        OAuth2RefreshTokenDO refreshToken = new OAuth2RefreshTokenDO()
 | 
			
		||||
//                .setId(generateRefreshToken())
 | 
			
		||||
//                .setUserId(userId).setUserType(userType)
 | 
			
		||||
//                .setExpiresTime(new Date(System.currentTimeMillis() + systemBizProperties.getRefreshTokenExpireTimeMillis()))
 | 
			
		||||
//                .setCreateIp(createIp);
 | 
			
		||||
//        oauth2RefreshTokenMapper.insert(refreshToken);
 | 
			
		||||
//        return refreshToken;
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    private OAuth2AccessTokenDO getOAuth2AccessToken(String accessToken) {
 | 
			
		||||
//        // 优先从 Redis 中获取
 | 
			
		||||
//        OAuth2AccessTokenDO accessTokenDO = oauth2AccessTokenRedisDAO.get(accessToken);
 | 
			
		||||
//        if (accessTokenDO != null) {
 | 
			
		||||
//            return accessTokenDO;
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        // 获取不到,从 MySQL 中获取
 | 
			
		||||
//        accessTokenDO = oauth2AccessTokenMapper.selectById(accessToken);
 | 
			
		||||
//        // 如果在 MySQL 存在,则往 Redis 中写入
 | 
			
		||||
//        if (accessTokenDO != null) {
 | 
			
		||||
//            oauth2AccessTokenRedisDAO.set(accessTokenDO);
 | 
			
		||||
//        }
 | 
			
		||||
//        return accessTokenDO;
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    /**
 | 
			
		||||
//     * 删除 accessToken 的 MySQL 与 Redis 的数据
 | 
			
		||||
//     *
 | 
			
		||||
//     * @param accessToken 访问令牌
 | 
			
		||||
//     */
 | 
			
		||||
//    private void deleteOAuth2AccessToken(String accessToken) {
 | 
			
		||||
//        // 删除 MySQL
 | 
			
		||||
//        oauth2AccessTokenMapper.deleteById(accessToken);
 | 
			
		||||
//        // 删除 Redis
 | 
			
		||||
//        oauth2AccessTokenRedisDAO.delete(accessToken);
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    private static String generateAccessToken() {
 | 
			
		||||
//        return StringUtils.uuid(true);
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    private static String generateRefreshToken() {
 | 
			
		||||
//        return StringUtils.uuid(true);
 | 
			
		||||
//    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user