add 新增 OAuth2 相关依赖以及配置 ;

update 更新登录接口, 返回 AccessToken (登录接口正常, 但无法获取 LoginUser) ;
This commit is contained in:
Michelle.Chung 2023-05-30 21:51:53 +08:00
parent fa99b7c9e3
commit 155fa7b205
12 changed files with 168 additions and 8 deletions

View File

@ -191,6 +191,13 @@
<version>${satoken.version}</version>
</dependency>
<!-- Sa-Token-OAuth2.0 模块 -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-oauth2</artifactId>
<version>${satoken.version}</version>
</dependency>
<!-- dynamic-datasource 多数据源-->
<dependency>
<groupId>com.baomidou</groupId>

View File

@ -53,13 +53,17 @@ public class AuthController {
@PostMapping("/login/{clientId}/{authType}")
public <T> R<LoginVo> login(@PathVariable String clientId,
@PathVariable String authType,
@RequestParam(required = false) String tenantId,
@Validated @RequestBody T loginBody) {
// FIXME 后续不用泛型传参考虑改为 req 获取
// 校验类型和id
loginService.checkAuthType(clientId, authType);
// FIXME 抽取出来校验租户前端没改暂时注释
// loginService.checkTenant(tenantId);
// 登录
LoginVo loginVo = new LoginVo();
IAuthStrategy authStrategy = AuthFactory.instance(authType);
String token = authStrategy.login(authStrategy.getLoginBody(loginBody));
String token = authStrategy.login(clientId, authStrategy.getLoginBody(loginBody));
loginVo.setToken(token);
return R.ok(loginVo);
}

View File

@ -16,6 +16,6 @@ public interface IAuthStrategy<T> {
/**
* 登录
*/
String login(T loginBody);
String login(String clientId, T loginBody);
}

View File

@ -46,7 +46,7 @@ public class EmailAuthStrategy implements IAuthStrategy<EmailLoginBody> {
}
@Override
public String login(EmailLoginBody loginBody) {
public String login(String clientId, EmailLoginBody loginBody) {
String tenantId = loginBody.getTenantId();
String email = loginBody.getEmail();
String emailCode = loginBody.getEmailCode();

View File

@ -1,5 +1,8 @@
package org.dromara.web.service.impl;
import cn.dev33.satoken.oauth2.logic.SaOAuth2Util;
import cn.dev33.satoken.oauth2.model.AccessTokenModel;
import cn.dev33.satoken.oauth2.model.RequestAuthModel;
import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
@ -51,7 +54,7 @@ public class PasswordAuthStrategy implements IAuthStrategy<LoginBody> {
}
@Override
public String login(LoginBody loginBody) {
public String login(String clientId, LoginBody loginBody) {
String tenantId = loginBody.getTenantId();
String username = loginBody.getUsername();
String password = loginBody.getPassword();
@ -75,7 +78,13 @@ public class PasswordAuthStrategy implements IAuthStrategy<LoginBody> {
loginService.recordLogininfor(loginUser.getTenantId(), username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
loginService.recordLoginInfo(user.getUserId());
return StpUtil.getTokenValue();
// FIXME 参考 demo 生成 AccessToken但是 loginUser 获取不到值未解决
RequestAuthModel ra = new RequestAuthModel();
ra.clientId = clientId;
ra.loginId = StpUtil.getLoginId();
AccessTokenModel at = SaOAuth2Util.generateAccessToken(ra, true);
return at.accessToken;
}
/**

View File

@ -46,7 +46,7 @@ public class SmsAuthStrategy implements IAuthStrategy<SmsLoginBody> {
}
@Override
public String login(SmsLoginBody loginBody) {
public String login(String clientId, SmsLoginBody loginBody) {
String tenantId = loginBody.getTenantId();
String phonenumber = loginBody.getPhonenumber();
String smsCode = loginBody.getSmsCode();

View File

@ -35,7 +35,7 @@ public class XcxAuthStrategy implements IAuthStrategy<XcxLoginBody> {
}
@Override
public String login(XcxLoginBody loginBody) {
public String login(String clientId, XcxLoginBody loginBody) {
// xcxCode 小程序调用 wx.login 授权后获取
String xcxCode = loginBody.getXcxCode();
// todo 以下自行实现

View File

@ -0,0 +1,40 @@
package org.dromara.common.core.domain.model;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 授权管理对象
*
* @author Michelle.Chung
*/
@Data
public class AuthBody implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 客户端id
*/
private String clientId;
/**
* 客户端key
*/
private String clientKey;
/**
* 客户端秘钥
*/
private String clientSecret;
/**
* 授权类型
*/
private String authType;
}

View File

@ -0,0 +1,19 @@
package org.dromara.common.core.service;
import org.dromara.common.core.domain.model.AuthBody;
/**
* 通用 认证服务
*
* @author Michelle.Chung
*/
public interface AuthService {
/**
* 获取认证授权对象
*
* @param clientId 客户端id
*/
AuthBody getAuthBody(String clientId);
}

View File

@ -36,6 +36,12 @@
<artifactId>sa-token-jwt</artifactId>
</dependency>
<!-- Sa-Token-OAuth2.0 模块 -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-oauth2</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,60 @@
package org.dromara.common.satoken.core.service;
import cn.dev33.satoken.oauth2.logic.SaOAuth2Template;
import cn.dev33.satoken.oauth2.model.SaClientModel;
import cn.dev33.satoken.stp.StpUtil;
import org.dromara.common.core.domain.model.AuthBody;
import org.dromara.common.core.service.AuthService;
import org.dromara.common.core.utils.SpringUtils;
import org.springframework.stereotype.Component;
/**
* Sa-Token-OAuth2 模块实现类
*
* @author Michelle.Chung
*/
@Component
public class SaOAuth2TemplateImpl extends SaOAuth2Template {
/**
* 重写 Access-Token 生成策略复用登录会话的Token
*
* @param clientId 应用id
* @param loginId 账号id
* @param scope 权限
*/
@Override
public String randomAccessToken(String clientId, Object loginId, String scope) {
String tokenValue = StpUtil.createLoginSession(loginId);
return tokenValue;
}
/**
* 根据 id 获取 Client 信息
*
* @param clientId 应用id
*/
@Override
public SaClientModel getClientModel(String clientId) {
AuthService authService = SpringUtils.getBean(AuthService.class);
AuthBody authBody = authService.getAuthBody(clientId);
return new SaClientModel()
.setClientId(clientId)
.setClientSecret(authBody.getClientSecret())
.setAllowUrl("*")
.setIsPassword(true);
}
/**
* 根据ClientId LoginId 获取openid
*
* @param clientId 应用id
* @param loginId 账号id
*/
@Override
public String getOpenid(String clientId, Object loginId) {
// 此为模拟数据真实环境需要从数据库查询
return "gr_SwoIN0MC1ewxHX_vfCW3BothWDZMMtx__";
}
}

View File

@ -1,5 +1,11 @@
package org.dromara.system.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import org.dromara.common.core.domain.model.AuthBody;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.exception.user.AuthTypeErrorException;
import org.dromara.common.core.service.AuthService;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
@ -27,7 +33,7 @@ import java.util.Collection;
*/
@RequiredArgsConstructor
@Service
public class SysAuthServiceImpl implements ISysAuthService {
public class SysAuthServiceImpl implements ISysAuthService, AuthService {
private final SysAuthMapper baseMapper;
@ -111,4 +117,13 @@ public class SysAuthServiceImpl implements ISysAuthService {
return baseMapper.deleteBatchIds(ids) > 0;
}
@Override
public AuthBody getAuthBody(String clientId) {
SysAuth sysAuth = baseMapper.selectOne(
new LambdaQueryWrapper<SysAuth>().eq(SysAuth::getClientId, clientId));
if (ObjectUtil.isEmpty(sysAuth)) {
throw new ServiceException("clientId 错误");
}
return BeanUtil.toBean(sysAuth, AuthBody.class);
}
}