From 4a1e657d85bf018d3b72f1f1de41788e57c6941f Mon Sep 17 00:00:00 2001 From: WendyYang Date: Thu, 4 Jan 2024 15:00:22 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BB=A3=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pm/api/common/config/AuthCodeProperties.java | 35 +++++++++++++ .../api/meeting/entity/config/WebProperties.java | 7 +++ .../pm/api/user/controller/UserAuthController.java | 53 +++++++++++++++++-- .../hz/pm/api/user/manage/AgentLoginManage.java | 32 ++++++++++++ .../com/hz/pm/api/user/manage/AuthCodeManage.java | 60 ++++++++++++++++++++++ .../com/hz/pm/api/user/model/vo/AuthCodeVO.java | 20 ++++++++ .../user/security/auth/agent/AgentAuthFilter.java | 22 ++++++-- .../auth/agent/AgentAuthSecurityConfig.java | 9 ++-- hz-pm-api/src/main/resources/application-dev.yml | 7 ++- hz-pm-api/src/main/resources/application-prod.yml | 8 ++- hz-pm-api/src/main/resources/security/auth-dev.yml | 1 + 11 files changed, 239 insertions(+), 15 deletions(-) create mode 100644 hz-pm-api/src/main/java/com/hz/pm/api/common/config/AuthCodeProperties.java create mode 100644 hz-pm-api/src/main/java/com/hz/pm/api/user/manage/AgentLoginManage.java create mode 100644 hz-pm-api/src/main/java/com/hz/pm/api/user/manage/AuthCodeManage.java create mode 100644 hz-pm-api/src/main/java/com/hz/pm/api/user/model/vo/AuthCodeVO.java diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/common/config/AuthCodeProperties.java b/hz-pm-api/src/main/java/com/hz/pm/api/common/config/AuthCodeProperties.java new file mode 100644 index 0000000..6560785 --- /dev/null +++ b/hz-pm-api/src/main/java/com/hz/pm/api/common/config/AuthCodeProperties.java @@ -0,0 +1,35 @@ +package com.hz.pm.api.common.config; + +import cn.hutool.core.util.RandomUtil; +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + *

+ * AuthCodeProperties + *

+ * + * @author WendyYang + * @since 00:15 2023/12/21 + */ +@Data +@ConfigurationProperties(prefix = "auth-code") +public class AuthCodeProperties { + + private String secretKey; + + /** + * authCode失效时间(单位:秒) + */ + private Integer expireTime = 30; + + /** + * authCode长度(最大:16~32) + */ + private Integer length = 16; + + public static void main(String[] args) { + System.out.println("secretKey:" + RandomUtil.randomString(32)); + } + +} diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/meeting/entity/config/WebProperties.java b/hz-pm-api/src/main/java/com/hz/pm/api/meeting/entity/config/WebProperties.java index 1a19608..b320696 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/meeting/entity/config/WebProperties.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/meeting/entity/config/WebProperties.java @@ -20,8 +20,15 @@ public class WebProperties { public static String webUrl; + public static String apiHost; + public static String provincialUrl; + @Value("${api-host:}") + private void setApiHost(String host) { + apiHost = host; + } + @Value("${expert-registration.url:/expertEnroll}") private void setExpertRegistrationUrl(String url) { expertRegistrationUrl = url; diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/user/controller/UserAuthController.java b/hz-pm-api/src/main/java/com/hz/pm/api/user/controller/UserAuthController.java index c8378b6..f9dfdd2 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/user/controller/UserAuthController.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/user/controller/UserAuthController.java @@ -2,9 +2,17 @@ package com.hz.pm.api.user.controller; import com.fasterxml.jackson.databind.ObjectMapper; +import com.hz.pm.api.common.config.AuthCodeProperties; +import com.hz.pm.api.meeting.entity.config.WebProperties; +import com.hz.pm.api.user.manage.AgentLoginManage; +import com.hz.pm.api.user.manage.AuthCodeManage; +import com.hz.pm.api.user.model.vo.AuthCodeVO; +import com.hz.pm.api.user.util.LoginUserUtil; +import com.ningdatech.basic.exception.BizException; import com.ningdatech.basic.util.StrPool; import com.hz.pm.api.common.model.constant.BizConst; import com.hz.pm.api.user.security.auth.constants.SessionTimeConstant; +import com.ningdatech.log.annotation.WebLog; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; @@ -35,6 +43,10 @@ import java.io.IOException; public class UserAuthController { private final ObjectMapper objectMapper; + private final AuthCodeManage authCodeManage; + private final AgentLoginManage agentLoginManage; + + private static final String AGENT_LOGIN_PATH = "/api/v1/user/auth/agent-login"; @PostMapping(value = "/login", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) @ApiOperation(value = "登陆") @@ -81,12 +93,43 @@ public class UserAuthController { response.getWriter().write(objectMapper.writeValueAsString(BizConst.UNAUTHENTICATED)); } - @PostMapping(value = "/agent-login", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) + @PostMapping(value = "/proxy/agent-login", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) @ApiOperation(value = "代登陆") - @ApiImplicitParams({ - @ApiImplicitParam(name = "userId", value = "账号", required = true, paramType = "form", dataType = "String")}) - public void agentLogin(@RequestParam(value = "userId") String userId) { - // 不实现任何内容,只是为了出api文档 + @WebLog("代登录(代理接口)") + public void agentLoginProxy(@RequestParam(value = "userId") Long userId, + @RequestParam(value = "username", required = false, defaultValue = "") String username, + @RequestParam(value = "timestamp") long timestamp, + @RequestParam(value = "sign") String sign, + HttpServletRequest request, + HttpServletResponse response) throws IOException { + if (System.currentTimeMillis() - timestamp > 5000) { + throw BizException.wrap("签名已过期"); + } + if (LoginUserUtil.getUserId().equals(userId)) { + throw BizException.wrap("代登录用户无效"); + } + String targetUserId = String.valueOf(userId); + if (!agentLoginManage.agentLoginProxySignCheck(targetUserId, sign)) { + throw BizException.wrap("签名错误"); + } + String authCode = authCodeManage.generateAuthCode(targetUserId); + String urlParam = "?userId=" + userId + "&username=" + username + "&authCode=" + authCode; + String path = WebProperties.apiHost + request.getContextPath() + AGENT_LOGIN_PATH; + response.sendRedirect(path + urlParam); + } + + @PostMapping(value = "/getAuthCode", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) + public AuthCodeVO getAuthCode(@RequestParam(value = "userId") String userId, + @RequestParam(value = "sign") String sign) { + String authCode = authCodeManage.generateAuthCode(userId, sign); + return new AuthCodeVO(authCode); + } + + @GetMapping(value = "/agent-login") + @ApiOperation(value = "代登陆") + public void agentLogin(@RequestParam(value = "userId") String userId, + @RequestParam(value = "username") String username, + @RequestParam(value = "authCode") String authCode) { } @PostMapping(value = "/mh-login", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/user/manage/AgentLoginManage.java b/hz-pm-api/src/main/java/com/hz/pm/api/user/manage/AgentLoginManage.java new file mode 100644 index 0000000..b2ce4d6 --- /dev/null +++ b/hz-pm-api/src/main/java/com/hz/pm/api/user/manage/AgentLoginManage.java @@ -0,0 +1,32 @@ +package com.hz.pm.api.user.manage; + +import cn.hutool.crypto.SecureUtil; +import cn.hutool.crypto.digest.HMac; +import com.hz.pm.api.user.util.LoginUserUtil; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +/** + *

+ * AgentLoginProxyManage + *

+ * + * @author WendyYang + * @since 09:35 2023/12/21 + */ +@Component +public class AgentLoginManage { + + /** + * 代登录代理接口:secretKey + */ + @Value("${agent-login.proxy.secret-key}") + private String agentLoginProxySecretKey; + + public boolean agentLoginProxySignCheck(String userId, String sign) { + HMac hmacMd5 = SecureUtil.hmacMd5(agentLoginProxySecretKey); + String digestHex = hmacMd5.digestHex(userId + "#" + LoginUserUtil.getUserId()); + return digestHex.equals(sign); + } + +} diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/user/manage/AuthCodeManage.java b/hz-pm-api/src/main/java/com/hz/pm/api/user/manage/AuthCodeManage.java new file mode 100644 index 0000000..409b0df --- /dev/null +++ b/hz-pm-api/src/main/java/com/hz/pm/api/user/manage/AuthCodeManage.java @@ -0,0 +1,60 @@ +package com.hz.pm.api.user.manage; + +import cn.hutool.core.util.RandomUtil; +import cn.hutool.crypto.SecureUtil; +import cn.hutool.crypto.digest.HMac; +import com.hz.pm.api.common.config.AuthCodeProperties; +import com.ningdatech.basic.exception.BizException; +import com.ningdatech.cache.model.cache.CacheKey; +import com.ningdatech.cache.repository.CachePlusOps; +import lombok.RequiredArgsConstructor; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.stereotype.Component; + +import java.time.Duration; + +/** + *

+ * AuthCodeManage + *

+ * + * @author WendyYang + * @since 23:59 2023/12/20 + */ +@Component +@RequiredArgsConstructor +@EnableConfigurationProperties(AuthCodeProperties.class) +public class AuthCodeManage { + + private final CachePlusOps cachePlusOps; + private final AuthCodeProperties authCodeProperties; + + private String generateAuthCode(String userId, boolean checkSign, String sign) { + if (checkSign) { + HMac hmacMd5 = SecureUtil.hmacMd5(authCodeProperties.getSecretKey()); + String digestHex = hmacMd5.digestHex(userId); + if (!digestHex.equals(sign)) { + throw BizException.wrap("获取授权码失败:签名错误"); + } + } + String authCode = RandomUtil.randomString(authCodeProperties.getLength()); + Duration duration = Duration.ofSeconds(authCodeProperties.getExpireTime()); + CacheKey key = new CacheKey(userId + "#" + authCode, duration); + cachePlusOps.set(key, userId); + return authCode; + } + + public String generateAuthCode(String userId, String sign) { + return generateAuthCode(userId, true, sign); + } + + public String generateAuthCode(String userId) { + return generateAuthCode(userId, false, null); + } + + public boolean authCodeCheck(String userId, String authCode) { + CacheKey key = new CacheKey(userId + "#" + authCode); + return cachePlusOps.del(key) > 0; + } + +} diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/user/model/vo/AuthCodeVO.java b/hz-pm-api/src/main/java/com/hz/pm/api/user/model/vo/AuthCodeVO.java new file mode 100644 index 0000000..171adb6 --- /dev/null +++ b/hz-pm-api/src/main/java/com/hz/pm/api/user/model/vo/AuthCodeVO.java @@ -0,0 +1,20 @@ +package com.hz.pm.api.user.model.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + *

+ * AuthCodeVO + *

+ * + * @author WendyYang + * @since 00:06 2023/12/21 + */ +@Data +@AllArgsConstructor +public class AuthCodeVO { + + private String authCode; + +} diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentAuthFilter.java b/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentAuthFilter.java index d7979e0..2cd40dc 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentAuthFilter.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentAuthFilter.java @@ -1,5 +1,7 @@ package com.hz.pm.api.user.security.auth.agent; +import com.hz.pm.api.common.util.StrUtils; +import com.hz.pm.api.user.manage.AuthCodeManage; import com.hz.pm.api.user.security.model.WebRequestDetails; import com.ningdatech.basic.exception.BizException; import org.apache.commons.lang3.StringUtils; @@ -27,10 +29,15 @@ public class AgentAuthFilter extends AbstractAuthenticationProcessingFilter { private static final String USER_ID_PARAMETER = "userId"; + private static final String AUTH_CODE = "authCode"; + + private final AuthCodeManage authCodeManage; + // =================================================================================================== - public AgentAuthFilter(String processingUrl) { + public AgentAuthFilter(String processingUrl,AuthCodeManage authCodeManage) { super(new AntPathRequestMatcher(processingUrl, HttpMethod.POST.name())); + this.authCodeManage = authCodeManage; } // ======================================================================================================== @@ -41,12 +48,17 @@ public class AgentAuthFilter extends AbstractAuthenticationProcessingFilter { if (request.getMethod().equals(HttpMethod.POST.name())) { throw new AuthenticationServiceException("请求方法错误"); } - String userId = request.getParameter(USER_ID_PARAMETER); + String userId = StrUtils.trim(request.getParameter(USER_ID_PARAMETER)); if (StringUtils.isBlank(userId)) { - throw new BadCredentialsException("用户id 不能为空"); + throw new BadCredentialsException("用户ID不能为空"); + } + String authCode = StrUtils.trim(request.getParameter(AUTH_CODE)); + if (StringUtils.isBlank(userId)) { + throw new BadCredentialsException("授权码不能为空"); + } + if (!authCodeManage.authCodeCheck(userId, authCode)) { + throw new BadCredentialsException("授权码已过期"); } - - userId = trim(userId); try { AgentAuthToken authRequest = new AgentAuthToken(userId, userId); authRequest.setDetails(new WebRequestDetails(request)); diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentAuthSecurityConfig.java b/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentAuthSecurityConfig.java index 84a2596..96f6e16 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentAuthSecurityConfig.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentAuthSecurityConfig.java @@ -1,5 +1,6 @@ package com.hz.pm.api.user.security.auth.agent; +import com.hz.pm.api.user.manage.AuthCodeManage; import com.hz.pm.api.user.security.config.AuthProperties; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.security.authentication.AuthenticationManager; @@ -28,21 +29,23 @@ public class AgentAuthSecurityConfig extends SecurityConfigurerAdapter