Files
youlai-boot/src/main/java/com/youlai/boot/security/provider/WxMiniAppCodeAuthenticationProvider.java
Ray.Hao c43e6dfb54 refactor(platform):重构平台模块包结构- 将 shared 包下的文件移动到 platform 包下
- 更新相关类的包引用路径
- 修改 application.yml 中的包扫描路径
-重命名 CaptchaInfo 类为 CaptchaVO 并调整包路径
- 移动 BusinessException 和相关安全类到 core 包- 更新 Codegen 相关类包路径
- 删除无用的条件判断代码块
2025-10-14 16:09:46 +08:00

98 lines
3.8 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.youlai.boot.security.provider;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.youlai.boot.security.model.SysUserDetails;
import com.youlai.boot.security.model.UserAuthCredentials;
import com.youlai.boot.security.model.WxMiniAppCodeAuthenticationToken;
import com.youlai.boot.system.service.UserService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.CredentialsExpiredException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
/**
* 微信小程序Code认证Provider
*
* @author 有来技术团队
* @since 2.0.0
*/
@Slf4j
public class WxMiniAppCodeAuthenticationProvider implements AuthenticationProvider {
private final UserService userService;
private final WxMaService wxMaService;
public WxMiniAppCodeAuthenticationProvider(UserService userService, WxMaService wxMaService) {
this.userService = userService;
this.wxMaService = wxMaService;
}
/**
* 微信认证逻辑,参考 Spring Security 认证密码校验流程
*
* @param authentication 认证对象
* @return 认证后的 Authentication 对象
* @throws AuthenticationException 认证异常
* @see org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider#authenticate(Authentication)
*/
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String code = (String) authentication.getPrincipal();
// 通过微信服务端验证 code 并获取用户会话信息
WxMaJscode2SessionResult sessionInfo;
try {
sessionInfo = wxMaService.getUserService().getSessionInfo(code);
} catch (WxErrorException e) {
throw new CredentialsExpiredException("微信登录 code 无效或已失效,请重新获取");
}
String openId = sessionInfo.getOpenid();
if (StrUtil.isBlank(openId)) {
throw new UsernameNotFoundException("未能获取到微信 OpenID请稍后重试");
}
// 根据微信 OpenID 查询用户信息
UserAuthCredentials userAuthCredentials = userService.getAuthCredentialsByOpenId(openId);
if (userAuthCredentials == null) {
// 用户不存在则注册
userService.registerOrBindWechatUser(openId);
// 再次查询用户信息,确保用户注册成功
userAuthCredentials = userService.getAuthCredentialsByOpenId(openId);
if (userAuthCredentials == null) {
throw new UsernameNotFoundException("用户注册失败,请稍后重试");
}
}
// 检查用户状态是否有效
if (ObjectUtil.notEqual(userAuthCredentials.getStatus(), 1)) {
throw new DisabledException("用户已被禁用");
}
// 构建认证后的用户详情信息
SysUserDetails userDetails = new SysUserDetails(userAuthCredentials);
// 创建已认证的Token
return WxMiniAppCodeAuthenticationToken.authenticated(
userDetails,
userDetails.getAuthorities()
);
}
@Override
public boolean supports(Class<?> authentication) {
return WxMiniAppCodeAuthenticationToken.class.isAssignableFrom(authentication);
}
}