feat: [auth] AuthController

This commit is contained in:
tjq 2024-02-11 11:04:20 +08:00
parent a1c12bf1c7
commit cf8153ae39
8 changed files with 127 additions and 14 deletions

View File

@ -0,0 +1,12 @@
package tech.powerjob.server.auth.common;
/**
* 常量
*
* @author tjq
* @since 2024/2/11
*/
public class AuthConstants {
public static final String JWT_NAME = "power_jwt";
}

View File

@ -1,6 +1,7 @@
package tech.powerjob.server.auth.common;
import lombok.Getter;
import tech.powerjob.common.exception.PowerJobException;
/**
* 鉴权相关错误
@ -9,7 +10,7 @@ import lombok.Getter;
* @since 2024/2/10
*/
@Getter
public class PowerJobAuthException extends RuntimeException {
public class PowerJobAuthException extends PowerJobException {
private final String code;

View File

@ -1,7 +1,13 @@
package tech.powerjob.server.auth.jwt.impl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import tech.powerjob.server.auth.jwt.SecretProvider;
import tech.powerjob.server.common.utils.DigestUtils;
import javax.annotation.Resource;
/**
* PowerJob 默认实现
@ -9,10 +15,33 @@ import tech.powerjob.server.auth.jwt.SecretProvider;
* @author tjq
* @since 2023/3/20
*/
@Slf4j
@Component
public class DefaultSecretProvider implements SecretProvider {
@Resource
private Environment environment;
private static final String PROPERTY_KEY = "spring.datasource.core.jdbc-url";
@Override
public String fetchSecretKey() {
// 考虑到大部分用户都是开箱即用此处还是提供一个相对安全的默认实现JDBC URL 部署时必会改skey 不固定更安全
try {
String propertyValue = environment.getProperty(PROPERTY_KEY);
if (StringUtils.isNotEmpty(propertyValue)) {
String md5 = DigestUtils.md5(propertyValue);
log.debug("[DefaultSecretProvider] propertyValue: {} ==> md5: {}", propertyValue, md5);
if (StringUtils.isNotEmpty(md5)) {
return md5;
}
}
} catch (Exception ignore) {
}
return "ZQQZJ";
}
}

View File

@ -18,14 +18,14 @@ public interface ThirdPartyLoginService {
/**
* 生成登陆的重定向 URL
* @param loginContext 上下文
* @param httpServletRequest http请求
* @return 重定向地址
*/
String generateLoginUrl(HttpServletRequest httpServletRequest);
/**
* 执行第三方登录
* @param loginContext 上下文
* @param loginRequest 上下文
* @return 登录地址
*/
ThirdPartyUser login(ThirdPartyLoginRequest loginRequest);

View File

@ -1,6 +1,7 @@
package tech.powerjob.server.auth.service.login;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.servlet.http.HttpServletRequest;
@ -11,6 +12,7 @@ import javax.servlet.http.HttpServletRequest;
* @since 2024/2/10
*/
@Data
@Accessors(chain = true)
public class LoginRequest {
/**

View File

@ -25,10 +25,11 @@ public interface PowerJobLoginService {
/**
* 获取第三方登录链接
* @param loginType 登录类型
* @param httpServletRequest http请求
* @return 重定向地址
*/
String fetchThirdPartyLoginUrl(HttpServletRequest httpServletRequest);
String fetchThirdPartyLoginUrl(String loginType, HttpServletRequest httpServletRequest);
/**
* 执行真正的登录请求底层调用第三方登录服务完成登录

View File

@ -8,6 +8,7 @@ import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tech.powerjob.server.auth.PowerJobUser;
import tech.powerjob.server.auth.common.AuthConstants;
import tech.powerjob.server.auth.common.AuthErrorCode;
import tech.powerjob.server.auth.common.PowerJobAuthException;
import tech.powerjob.server.auth.jwt.JwtService;
@ -43,7 +44,7 @@ public class PowerJobLoginServiceImpl implements PowerJobLoginService {
private final UserInfoRepository userInfoRepository;
private final Map<String, ThirdPartyLoginService> code2ThirdPartyLoginService;
private static final String JWT_NAME = "power_jwt";
private static final String KEY_USERNAME = "userName";
@ -66,8 +67,9 @@ public class PowerJobLoginServiceImpl implements PowerJobLoginService {
}
@Override
public String fetchThirdPartyLoginUrl(HttpServletRequest httpServletRequest) {
return null;
public String fetchThirdPartyLoginUrl(String type, HttpServletRequest httpServletRequest) {
final ThirdPartyLoginService thirdPartyLoginService = fetchBizLoginService(type);
return thirdPartyLoginService.generateLoginUrl(httpServletRequest);
}
@Override
@ -137,10 +139,10 @@ public class PowerJobLoginServiceImpl implements PowerJobLoginService {
private Optional<String> parseUserName(HttpServletRequest httpServletRequest) {
// headercookie 都能获取
String jwtStr = httpServletRequest.getHeader(JWT_NAME);
String jwtStr = httpServletRequest.getHeader(AuthConstants.JWT_NAME);
if (StringUtils.isEmpty(jwtStr)) {
for (Cookie cookie : httpServletRequest.getCookies()) {
if (cookie.getName().equals(JWT_NAME)) {
if (cookie.getName().equals(AuthConstants.JWT_NAME)) {
jwtStr = cookie.getValue();
}
}

View File

@ -1,12 +1,19 @@
package tech.powerjob.server.web.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import tech.powerjob.common.response.ResultDTO;
import tech.powerjob.server.auth.PowerJobUser;
import tech.powerjob.server.auth.common.AuthConstants;
import tech.powerjob.server.auth.login.LoginTypeInfo;
import tech.powerjob.server.auth.service.login.LoginRequest;
import tech.powerjob.server.auth.service.login.PowerJobLoginService;
import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Optional;
/**
* 登录 & 权限相关
@ -18,9 +25,68 @@ import java.util.List;
@RequestMapping("/auth")
public class AuthController {
@GetMapping("/listSupportLoginTypes")
@Resource
private PowerJobLoginService powerJobLoginService;
@GetMapping("/supportLoginTypes")
public ResultDTO<List<LoginTypeInfo>> listSupportLoginTypes() {
return null;
return ResultDTO.success(powerJobLoginService.fetchSupportLoginTypes());
}
@GetMapping("/thirdPartyLoginUrl")
public ResultDTO<String> getThirdPartyLoginUrl(String type, HttpServletRequest request) {
String url = powerJobLoginService.fetchThirdPartyLoginUrl(type, request);
return ResultDTO.success(url);
}
/**
* 第三方账号体系回调登录接口eg, 接受钉钉登录回调
* @param httpServletRequest 请求
* @param httpServletResponse 响应
* @return 登录结果
*/
@RequestMapping(value = "/thirdPartyLoginCallback", method = {RequestMethod.GET, RequestMethod.POST})
public ResultDTO<PowerJobUser> loginCallback(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
LoginRequest loginContext = new LoginRequest().setHttpServletRequest(httpServletRequest);
// 常见登录组件的标准规范钉钉企业微信飞书第三方原样透传开发者在对接第三方登录体系时可能需要修改此处 type 回填
final String state = httpServletRequest.getParameter("state");
loginContext.setLoginType(state);
final PowerJobUser powerJobUser = powerJobLoginService.doLogin(loginContext);
fillJwt4LoginUser(powerJobUser, httpServletResponse);
return ResultDTO.success(powerJobUser);
}
/**
* 第三方账号体系直接登录接口eg, 接受 PowerJob 自带账号密码体系的登录请求
* @param loginRequest 登录请求
* @param httpServletResponse 响应
* @return 登录结果
*/
@PostMapping("/thirdPartyLoginDirect")
public ResultDTO<PowerJobUser> selfLogin(LoginRequest loginRequest, HttpServletResponse httpServletResponse) {
try {
final PowerJobUser powerJobUser = powerJobLoginService.doLogin(loginRequest);
if (powerJobUser == null) {
return ResultDTO.failed("USER_NOT_FOUND");
}
fillJwt4LoginUser(powerJobUser, httpServletResponse);
return ResultDTO.success(powerJobUser);
} catch (Exception e) {
return ResultDTO.failed(e.getMessage());
}
}
@GetMapping(value = "/ifLogin")
public ResultDTO<PowerJobUser> ifLogin(HttpServletRequest httpServletRequest) {
final Optional<PowerJobUser> powerJobUser = powerJobLoginService.ifLogin(httpServletRequest);
return powerJobUser.map(ResultDTO::success).orElseGet(() -> ResultDTO.failed("LOGIN_FAILED"));
}
private void fillJwt4LoginUser(PowerJobUser powerJobUser, HttpServletResponse httpServletResponse) {
httpServletResponse.addCookie(new Cookie(AuthConstants.JWT_NAME, powerJobUser.getJwtToken()));
}
}