From 5148363e5f628e6f87cb4c9e5d861aaa08d5654e Mon Sep 17 00:00:00 2001 From: WendyYang Date: Thu, 4 Jan 2024 19:08:06 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=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 ---------- .../com/hz/pm/api/common/config/AuthCodeProps.java | 37 ++++++++++ .../projectlib/model/req/ProjectApprovedReq.java | 1 - .../pm/api/user/controller/UserAuthController.java | 40 +++++------ .../hz/pm/api/user/manage/AgentLoginManage.java | 1 - .../hz/pm/api/user/manage/AuthCodeLoginManage.java | 70 +++++++++++++++++++ .../com/hz/pm/api/user/manage/AuthCodeManage.java | 60 ---------------- .../user/security/auth/agent/AgentAuthFilter.java | 81 ---------------------- .../security/auth/agent/AgentAuthProvider.java | 38 ---------- .../auth/agent/AgentAuthSecurityConfig.java | 61 ---------------- .../user/security/auth/agent/AgentAuthToken.java | 75 -------------------- .../auth/agent/AgentLoginUserDetailService.java | 41 ----------- .../security/auth/code/AuthCodeLoginFilter.java | 60 ++++++++++++++++ .../security/auth/code/AuthCodeLoginProvider.java | 38 ++++++++++ .../auth/code/AuthCodeLoginSecurityConfig.java | 61 ++++++++++++++++ .../auth/code/AuthCodeLoginUserDetailService.java | 44 ++++++++++++ .../api/user/security/auth/code/AuthCodeToken.java | 77 ++++++++++++++++++++ .../api/user/security/config/AuthProperties.java | 2 +- .../user/security/config/WebSecurityConfig.java | 6 +- hz-pm-api/src/main/resources/security/auth-dev.yml | 2 +- .../src/main/resources/security/auth-prod.yml | 2 +- 21 files changed, 412 insertions(+), 420 deletions(-) delete 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/common/config/AuthCodeProps.java create mode 100644 hz-pm-api/src/main/java/com/hz/pm/api/user/manage/AuthCodeLoginManage.java delete mode 100644 hz-pm-api/src/main/java/com/hz/pm/api/user/manage/AuthCodeManage.java delete mode 100644 hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentAuthFilter.java delete mode 100644 hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentAuthProvider.java delete mode 100644 hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentAuthSecurityConfig.java delete mode 100644 hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentAuthToken.java delete mode 100644 hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentLoginUserDetailService.java create mode 100644 hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/code/AuthCodeLoginFilter.java create mode 100644 hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/code/AuthCodeLoginProvider.java create mode 100644 hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/code/AuthCodeLoginSecurityConfig.java create mode 100644 hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/code/AuthCodeLoginUserDetailService.java create mode 100644 hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/code/AuthCodeToken.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 deleted file mode 100644 index 6560785..0000000 --- a/hz-pm-api/src/main/java/com/hz/pm/api/common/config/AuthCodeProperties.java +++ /dev/null @@ -1,35 +0,0 @@ -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/common/config/AuthCodeProps.java b/hz-pm-api/src/main/java/com/hz/pm/api/common/config/AuthCodeProps.java new file mode 100644 index 0000000..45a63a7 --- /dev/null +++ b/hz-pm-api/src/main/java/com/hz/pm/api/common/config/AuthCodeProps.java @@ -0,0 +1,37 @@ +package com.hz.pm.api.common.config; + +import cn.hutool.core.util.RandomUtil; +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; + +import java.util.UUID; + +/** + *

+ * AuthCodeProps + *

+ * + * @author WendyYang + * @since 00:15 2023/12/21 + */ +@Data +@ConfigurationProperties(prefix = "auth-code") +public class AuthCodeProps { + + private String secretKey; + + /** + * authCode失效时间(单位:秒) + */ + private Integer expireTime = 10; + + /** + * authCode长度(最大:24~32) + */ + private Integer length = 24; + + public static void main(String[] args) { + System.out.println("secretKey:" + RandomUtil.randomString(24)); + } + +} diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/projectlib/model/req/ProjectApprovedReq.java b/hz-pm-api/src/main/java/com/hz/pm/api/projectlib/model/req/ProjectApprovedReq.java index 21b20bb..4286e2a 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/projectlib/model/req/ProjectApprovedReq.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/projectlib/model/req/ProjectApprovedReq.java @@ -56,7 +56,6 @@ public class ProjectApprovedReq { private Long approvedFileId; @ApiModelProperty("建设方案文件ID") - @NotNull(message = "建设方案不能为空") private Long buildPlanFileId; } 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 bd2e73e..8997b49 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,10 +2,9 @@ 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.manage.AuthCodeLoginManage; import com.hz.pm.api.user.model.vo.AuthCodeVO; import com.hz.pm.api.user.util.LoginUserUtil; import com.ningdatech.basic.exception.BizException; @@ -43,10 +42,10 @@ import java.io.IOException; public class UserAuthController { private final ObjectMapper objectMapper; - private final AuthCodeManage authCodeManage; + private final AuthCodeLoginManage authCodeLoginManage; private final AgentLoginManage agentLoginManage; - private static final String AGENT_LOGIN_PATH = "/api/v1/user/auth/agent-login"; + private static final String AUTH_CODE_LOGIN_PATH = "/api/v1/user/auth/authCodeLogin"; @PostMapping(value = "/login", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) @ApiOperation(value = "登陆") @@ -93,25 +92,25 @@ public class UserAuthController { response.getWriter().write(objectMapper.writeValueAsString(BizConst.UNAUTHENTICATED)); } - @PostMapping(value = "/proxy/agent-login", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) + @PostMapping(value = "/proxy/authCodeLogin", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) @ApiOperation(value = "代登陆") @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 { + public void proxyAuthCodeLogin(@RequestParam(value = "userId") Long userId, + @RequestParam(value = "username") String username, + @RequestParam(value = "timestamp") long timestamp, + @RequestParam(value = "sign") String sign, + HttpServletRequest request, + HttpServletResponse response) throws IOException { if (LoginUserUtil.getUserId().equals(userId)) { - throw BizException.wrap("代登录用户无效"); + throw BizException.wrap("代登录用户无效:%s", username); } String targetUserId = String.valueOf(userId); if (!agentLoginManage.agentLoginProxySignCheck(targetUserId, timestamp, 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; + String authCode = authCodeLoginManage.generateAuthCode(targetUserId); + String urlParam = "?authCode=" + authCode; + String path = WebProperties.apiHost + request.getContextPath() + AUTH_CODE_LOGIN_PATH; response.sendRedirect(path + urlParam); } @@ -119,15 +118,14 @@ public class UserAuthController { public AuthCodeVO getAuthCode(@RequestParam(value = "userId") String userId, @RequestParam(value = "timestamp") Long timestamp, @RequestParam(value = "sign") String sign) { - String authCode = authCodeManage.generateAuthCode(userId, timestamp, sign); + String authCode = authCodeLoginManage.generateAuthCode(userId, timestamp, 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) { + @GetMapping(value = "/authCodeLogin", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) + @ApiOperation(value = "授权码登录") + public void authCodeLogin(@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 index aafc454..5b1a4e2 100644 --- 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 @@ -2,7 +2,6 @@ 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; diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/user/manage/AuthCodeLoginManage.java b/hz-pm-api/src/main/java/com/hz/pm/api/user/manage/AuthCodeLoginManage.java new file mode 100644 index 0000000..cfeda85 --- /dev/null +++ b/hz-pm-api/src/main/java/com/hz/pm/api/user/manage/AuthCodeLoginManage.java @@ -0,0 +1,70 @@ +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.AuthCodeProps; +import com.ningdatech.basic.exception.BizException; +import com.ningdatech.cache.model.cache.CacheKey; +import com.ningdatech.cache.repository.CachePlusOps; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.stereotype.Component; + +import java.time.Duration; + +/** + *

+ * AuthCodeLoginManage + *

+ * + * @author WendyYang + * @since 23:59 2023/12/20 + */ +@Slf4j +@Component +@RequiredArgsConstructor +@EnableConfigurationProperties(AuthCodeProps.class) +public class AuthCodeLoginManage { + + private final CachePlusOps cachePlusOps; + private final AuthCodeProps authCodeProps; + + private String generateAuthCode(String userId, boolean checkSign, Long timestamp, String sign) { + if (checkSign) { + if (System.currentTimeMillis() - timestamp > 5000) { + throw BizException.wrap("签名无效"); + } + HMac hmacMd5 = SecureUtil.hmacMd5(authCodeProps.getSecretKey()); + String digestHex = hmacMd5.digestHex(userId + "#" + timestamp); + if (!digestHex.equals(sign)) { + throw BizException.wrap("获取授权码失败:签名错误"); + } + } + String authCode = RandomUtil.randomString(authCodeProps.getLength()); + Duration duration = Duration.ofSeconds(authCodeProps.getExpireTime()); + CacheKey key = new CacheKey(authCode, duration); + cachePlusOps.set(key, userId); + log.info("生成授权码:{} -> {}", userId, authCode); + return authCode; + } + + public String generateAuthCode(String userId, Long timestamp, String sign) { + return generateAuthCode(userId, true, timestamp, sign); + } + + public String generateAuthCode(String userId) { + return generateAuthCode(userId, false, null, null); + } + + public String getUserIdByAuthCode(String authCode) { + CacheKey key = new CacheKey(authCode); + try { + return cachePlusOps.get(key); + } finally { + cachePlusOps.del(key); + } + } + +} 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 deleted file mode 100644 index f3028a7..0000000 --- a/hz-pm-api/src/main/java/com/hz/pm/api/user/manage/AuthCodeManage.java +++ /dev/null @@ -1,60 +0,0 @@ -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, Long timestamp, String sign) { - if (checkSign) { - HMac hmacMd5 = SecureUtil.hmacMd5(authCodeProperties.getSecretKey()); - String digestHex = hmacMd5.digestHex(userId + "#" + timestamp); - 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, Long timestamp, String sign) { - return generateAuthCode(userId, true, timestamp, sign); - } - - public String generateAuthCode(String userId) { - return generateAuthCode(userId, false, null, 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/security/auth/agent/AgentAuthFilter.java b/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentAuthFilter.java deleted file mode 100644 index 2cd40dc..0000000 --- a/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentAuthFilter.java +++ /dev/null @@ -1,81 +0,0 @@ -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; -import org.springframework.http.HttpMethod; -import org.springframework.security.authentication.AuthenticationServiceException; -import org.springframework.security.authentication.BadCredentialsException; -import org.springframework.security.authentication.InternalAuthenticationServiceException; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - *

- * AgentAuthFilter - *

- * - * @author WendyYang - * @since 13:25 2023/12/28 - */ -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,AuthCodeManage authCodeManage) { - super(new AntPathRequestMatcher(processingUrl, HttpMethod.POST.name())); - this.authCodeManage = authCodeManage; - } - - // ======================================================================================================== - - @Override - public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) - throws AuthenticationException { - if (request.getMethod().equals(HttpMethod.POST.name())) { - throw new AuthenticationServiceException("请求方法错误"); - } - String userId = StrUtils.trim(request.getParameter(USER_ID_PARAMETER)); - if (StringUtils.isBlank(userId)) { - 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("授权码已过期"); - } - try { - AgentAuthToken authRequest = new AgentAuthToken(userId, userId); - authRequest.setDetails(new WebRequestDetails(request)); - return this.getAuthenticationManager().authenticate(authRequest); - } catch (AuthenticationException e) { - throw new BadCredentialsException("用户id 不能为空"); - } catch (BizException e) { - throw new BadCredentialsException(e.getMessage()); - } catch (Exception e) { - throw new InternalAuthenticationServiceException("授权失败:", e); - } - } - - private String trim(String trimStr) { - if (StringUtils.isNotBlank(trimStr)) { - return trimStr.trim(); - } - return null; - } -} diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentAuthProvider.java b/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentAuthProvider.java deleted file mode 100644 index 2b2ff77..0000000 --- a/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentAuthProvider.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.hz.pm.api.user.security.auth.agent; - -import lombok.Setter; -import org.springframework.security.authentication.AuthenticationProvider; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; - -/** - *

- * AgentAuthProvider - *

- * - * @author WendyYang - * @since 20:41 2023/12/15 - */ -@Setter -public class AgentAuthProvider implements AuthenticationProvider { - - private UserDetailsService userDetailsService; - - @Override - public Authentication authenticate(Authentication authentication) throws AuthenticationException { - AgentAuthToken authenticationToken = (AgentAuthToken) authentication; - String principal = (String) authenticationToken.getPrincipal(); - - UserDetails user = userDetailsService.loadUserByUsername(principal); - // 将用户定义的user放入token中,这样可以在session中查询到所有自定义的用户信息 - return new AgentAuthToken(user, user.getPassword(), user.getAuthorities()); - } - - @Override - public boolean supports(Class authentication) { - return AgentAuthToken.class.isAssignableFrom(authentication); - } - -} 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 deleted file mode 100644 index 96f6e16..0000000 --- a/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentAuthSecurityConfig.java +++ /dev/null @@ -1,61 +0,0 @@ -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; -import org.springframework.security.config.annotation.SecurityConfigurerAdapter; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.web.DefaultSecurityFilterChain; -import org.springframework.security.web.authentication.AuthenticationFailureHandler; -import org.springframework.security.web.authentication.AuthenticationSuccessHandler; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import org.springframework.stereotype.Component; - -/** - *

- * AgentAuthSecurityConfig - *

- * - * @author WendyYang - * @since 14:24 2023/12/16 - */ -@Component -public class AgentAuthSecurityConfig extends SecurityConfigurerAdapter { - - - protected final AuthenticationSuccessHandler defaultLoginSuccessHandler; - protected final AuthenticationFailureHandler defaultLoginFailureHandler; - private final UserDetailsService agentLoginUserDetailService; - private final AuthProperties authProperties; - private final AuthCodeManage authCodeManage; - - public AgentAuthSecurityConfig(@Qualifier(value = "defaultLoginSuccessHandler") AuthenticationSuccessHandler loginSuccessHandler, - @Qualifier(value = "defaultLoginFailureHandler") AuthenticationFailureHandler loginFailureHandler, - @Qualifier(value = "agentLoginUserDetailService") UserDetailsService agentLoginUserDetailService, - AuthProperties authProperties, - AuthCodeManage authCodeManage) { - this.defaultLoginSuccessHandler = loginSuccessHandler; - this.defaultLoginFailureHandler = loginFailureHandler; - this.agentLoginUserDetailService = agentLoginUserDetailService; - this.authProperties = authProperties; - this.authCodeManage = authCodeManage; - } - - @Override - public void configure(HttpSecurity http) { - AgentAuthFilter agentAuthFilter = new AgentAuthFilter(authProperties.getAgentLoginUrl(), authCodeManage); - AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class); - agentAuthFilter.setAuthenticationManager(authenticationManager); - agentAuthFilter.setAuthenticationSuccessHandler(defaultLoginSuccessHandler); - agentAuthFilter.setAuthenticationFailureHandler(defaultLoginFailureHandler); - - AgentAuthProvider authenticationProvider = new AgentAuthProvider(); - authenticationProvider.setUserDetailsService(agentLoginUserDetailService); - - http.authenticationProvider(authenticationProvider) - .addFilterAfter(agentAuthFilter, UsernamePasswordAuthenticationFilter.class); - } - -} diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentAuthToken.java b/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentAuthToken.java deleted file mode 100644 index e861acf..0000000 --- a/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentAuthToken.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.hz.pm.api.user.security.auth.agent; - -import org.springframework.security.authentication.AbstractAuthenticationToken; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.SpringSecurityCoreVersion; - -import java.util.Collection; - -/** - * @Author LiuXinXin - * @Date 2020/8/3 8:52 下午 - * @Version 1.0 - **/ -public class AgentAuthToken extends AbstractAuthenticationToken { - - private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; - - private final Object principal; - - private final Object credentials; - - /** - * This constructor can be safely used by any code that wishes to create a - * UsernamePasswordAuthenticationToken, as the {@link #isAuthenticated()} will return - * false. - */ - public AgentAuthToken(String principal, String credentials) { - super(null); - this.principal = principal; - this.credentials = credentials; - setAuthenticated(false); - } - - /** - * This constructor should only be used by AuthenticationManager or AuthenticationProvider - * implementations that are satisfied with producing a trusted (i.e. {@link #isAuthenticated()} = true) - * authentication token. - * - * @param principal - * @param authorities - */ - public AgentAuthToken(Object principal, Object credentials, - Collection authorities) { - super(authorities); - this.principal = principal; - this.credentials = credentials; - // must use super, as we override - super.setAuthenticated(true); - } - - @Override - public Object getCredentials() { - return this.credentials; - } - - @Override - public Object getPrincipal() { - return this.principal; - } - - @Override - public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { - if (isAuthenticated) { - throw new IllegalArgumentException( - "Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead"); - } - super.setAuthenticated(false); - } - - @Override - public void eraseCredentials() { - super.eraseCredentials(); - } - -} diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentLoginUserDetailService.java b/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentLoginUserDetailService.java deleted file mode 100644 index 3573156..0000000 --- a/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/agent/AgentLoginUserDetailService.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.hz.pm.api.user.security.auth.agent; - - -import com.hz.pm.api.common.helper.UserInfoHelper; -import com.hz.pm.api.user.model.enumeration.UserAvailableEnum; -import com.hz.pm.api.user.convert.UserInfoConvertor; -import com.hz.pm.api.user.security.model.UserFullInfoDTO; -import com.hz.pm.api.user.security.model.UserInfoDetails; -import com.hz.pm.api.user.security.validate.CommonLoginException; -import lombok.RequiredArgsConstructor; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.stereotype.Service; - -import java.util.Objects; - -/** - * @author LiuXinXin - * @date 2022/9/30 上午9:49 - */ - -@Service("agentLoginUserDetailService") -@RequiredArgsConstructor -public class AgentLoginUserDetailService implements UserDetailsService { - - private final UserInfoHelper userInfoHelper; - - @Override - public UserInfoDetails loadUserByUsername(String username) throws UsernameNotFoundException { - Long userId = Long.parseLong(username); - UserFullInfoDTO ufi = userInfoHelper.getUserFullInfo(userId); - if (Objects.isNull(ufi)) { - throw new UsernameNotFoundException("用户不存在"); - } - if (UserAvailableEnum.DISABLE.equals(ufi.getAvailable())) { - throw new CommonLoginException("账号已禁用"); - } - return UserInfoConvertor.convert(ufi); - } - -} diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/code/AuthCodeLoginFilter.java b/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/code/AuthCodeLoginFilter.java new file mode 100644 index 0000000..e411f6f --- /dev/null +++ b/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/code/AuthCodeLoginFilter.java @@ -0,0 +1,60 @@ +package com.hz.pm.api.user.security.auth.code; + +import cn.hutool.core.util.StrUtil; +import com.hz.pm.api.common.util.StrUtils; +import com.hz.pm.api.user.manage.AuthCodeLoginManage; +import com.hz.pm.api.user.security.model.WebRequestDetails; +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.HttpMethod; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + *

+ * AuthCodeFilter + *

+ * + * @author WendyYang + * @since 13:25 2023/12/28 + */ +public class AuthCodeLoginFilter extends AbstractAuthenticationProcessingFilter { + + private static final String AUTH_CODE = "authCode"; + + private final AuthCodeLoginManage authCodeLoginManage; + + // =================================================================================================== + + public AuthCodeLoginFilter(String processingUrl, AuthCodeLoginManage authCodeLoginManage) { + super(new AntPathRequestMatcher(processingUrl, HttpMethod.GET.name())); + this.authCodeLoginManage = authCodeLoginManage; + } + + // ======================================================================================================== + + @Override + public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) { + String authCode = StrUtils.trim(request.getParameter(AUTH_CODE)); + if (StringUtils.isBlank(authCode)) { + throw new BadCredentialsException("授权码不能为空"); + } + String userId = authCodeLoginManage.getUserIdByAuthCode(authCode); + if (StrUtil.isBlank(userId)) { + throw new BadCredentialsException("授权码无效"); + } + try { + AuthCodeToken authRequest = new AuthCodeToken(userId, userId); + authRequest.setDetails(new WebRequestDetails(request)); + return this.getAuthenticationManager().authenticate(authRequest); + } catch (Exception e) { + logger.error(e.getMessage(), e); + throw new BadCredentialsException("授权失败"); + } + } + +} diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/code/AuthCodeLoginProvider.java b/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/code/AuthCodeLoginProvider.java new file mode 100644 index 0000000..fc2b283 --- /dev/null +++ b/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/code/AuthCodeLoginProvider.java @@ -0,0 +1,38 @@ +package com.hz.pm.api.user.security.auth.code; + +import lombok.Setter; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; + +/** + *

+ * AgentAuthProvider + *

+ * + * @author WendyYang + * @since 20:41 2023/12/15 + */ +@Setter +public class AuthCodeLoginProvider implements AuthenticationProvider { + + private UserDetailsService userDetailsService; + + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + AuthCodeToken authenticationToken = (AuthCodeToken) authentication; + String principal = (String) authenticationToken.getPrincipal(); + + UserDetails user = userDetailsService.loadUserByUsername(principal); + // 将用户定义的user放入token中,这样可以在session中查询到所有自定义的用户信息 + return new AuthCodeToken(user, user.getPassword(), user.getAuthorities()); + } + + @Override + public boolean supports(Class authentication) { + return AuthCodeToken.class.isAssignableFrom(authentication); + } + +} diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/code/AuthCodeLoginSecurityConfig.java b/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/code/AuthCodeLoginSecurityConfig.java new file mode 100644 index 0000000..530fee8 --- /dev/null +++ b/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/code/AuthCodeLoginSecurityConfig.java @@ -0,0 +1,61 @@ +package com.hz.pm.api.user.security.auth.code; + +import com.hz.pm.api.user.manage.AuthCodeLoginManage; +import com.hz.pm.api.user.security.config.AuthProperties; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.SecurityConfigurerAdapter; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.web.DefaultSecurityFilterChain; +import org.springframework.security.web.authentication.AuthenticationFailureHandler; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.stereotype.Component; + +/** + *

+ * AuthCodeSecurityConfig + *

+ * + * @author WendyYang + * @since 16:02 2024/1/4 + */ +@Component +public class AuthCodeLoginSecurityConfig extends SecurityConfigurerAdapter { + + + protected final AuthenticationSuccessHandler defaultLoginSuccessHandler; + protected final AuthenticationFailureHandler defaultLoginFailureHandler; + private final UserDetailsService userDetailsService; + private final AuthProperties authProps; + private final AuthCodeLoginManage authCodeLoginManage; + + public AuthCodeLoginSecurityConfig(@Qualifier(value = "defaultLoginSuccessHandler") AuthenticationSuccessHandler loginSuccessHandler, + @Qualifier(value = "defaultLoginFailureHandler") AuthenticationFailureHandler loginFailureHandler, + @Qualifier(value = "authCodeLoginUserDetailService") UserDetailsService userDetailsService, + AuthProperties authProps, + AuthCodeLoginManage authCodeLoginManage) { + this.defaultLoginSuccessHandler = loginSuccessHandler; + this.defaultLoginFailureHandler = loginFailureHandler; + this.userDetailsService = userDetailsService; + this.authProps = authProps; + this.authCodeLoginManage = authCodeLoginManage; + } + + @Override + public void configure(HttpSecurity http) { + AuthCodeLoginFilter filter = new AuthCodeLoginFilter(authProps.getAuthCodeLoginUrl(), authCodeLoginManage); + AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class); + filter.setAuthenticationManager(authenticationManager); + filter.setAuthenticationSuccessHandler(defaultLoginSuccessHandler); + filter.setAuthenticationFailureHandler(defaultLoginFailureHandler); + + AuthCodeLoginProvider authenticationProvider = new AuthCodeLoginProvider(); + authenticationProvider.setUserDetailsService(userDetailsService); + + http.authenticationProvider(authenticationProvider) + .addFilterAfter(filter, UsernamePasswordAuthenticationFilter.class); + } + +} diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/code/AuthCodeLoginUserDetailService.java b/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/code/AuthCodeLoginUserDetailService.java new file mode 100644 index 0000000..ea7599b --- /dev/null +++ b/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/code/AuthCodeLoginUserDetailService.java @@ -0,0 +1,44 @@ +package com.hz.pm.api.user.security.auth.code; + + +import com.hz.pm.api.common.helper.UserInfoHelper; +import com.hz.pm.api.user.convert.UserInfoConvertor; +import com.hz.pm.api.user.model.enumeration.UserAvailableEnum; +import com.hz.pm.api.user.security.model.UserFullInfoDTO; +import com.hz.pm.api.user.security.model.UserInfoDetails; +import com.hz.pm.api.user.security.validate.CommonLoginException; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +import java.util.Objects; + +/** + *

+ * AuthCodeLoginUserDetailService + *

+ * + * @author WendyYang + * @since 15:57 2024/1/4 + */ +@Service("authCodeLoginUserDetailService") +@RequiredArgsConstructor +public class AuthCodeLoginUserDetailService implements UserDetailsService { + + private final UserInfoHelper userInfoHelper; + + @Override + public UserInfoDetails loadUserByUsername(String username) throws UsernameNotFoundException { + Long userId = Long.parseLong(username); + UserFullInfoDTO ufi = userInfoHelper.getUserFullInfo(userId); + if (Objects.isNull(ufi)) { + throw new UsernameNotFoundException("用户不存在"); + } + if (UserAvailableEnum.DISABLE.equals(ufi.getAvailable())) { + throw new CommonLoginException("账号已禁用"); + } + return UserInfoConvertor.convert(ufi); + } + +} diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/code/AuthCodeToken.java b/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/code/AuthCodeToken.java new file mode 100644 index 0000000..63c8eb7 --- /dev/null +++ b/hz-pm-api/src/main/java/com/hz/pm/api/user/security/auth/code/AuthCodeToken.java @@ -0,0 +1,77 @@ +package com.hz.pm.api.user.security.auth.code; + +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.SpringSecurityCoreVersion; + +import java.util.Collection; + +/** + *

+ * AuthCodeToken + *

+ * + * @author WendyYang + * @since 15:45 2024/1/4 + */ +public class AuthCodeToken extends AbstractAuthenticationToken { + + private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; + + private final Object principal; + + private final Object credentials; + + /** + * This constructor can be safely used by any code that wishes to create a + * UsernamePasswordAuthenticationToken, as the {@link #isAuthenticated()} will return + * false. + */ + public AuthCodeToken(String principal, String credentials) { + super(null); + this.principal = principal; + this.credentials = credentials; + setAuthenticated(false); + } + + /** + * This constructor should only be used by AuthenticationManager or AuthenticationProvider + * implementations that are satisfied with producing a trusted (i.e. {@link #isAuthenticated()} = true) + * authentication token. + * + * @param principal + * @param authorities + */ + public AuthCodeToken(Object principal, Object credentials, + Collection authorities) { + super(authorities); + this.principal = principal; + this.credentials = credentials; + super.setAuthenticated(true); + } + + @Override + public Object getCredentials() { + return this.credentials; + } + + @Override + public Object getPrincipal() { + return this.principal; + } + + @Override + public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { + if (isAuthenticated) { + throw new IllegalArgumentException( + "Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead"); + } + super.setAuthenticated(false); + } + + @Override + public void eraseCredentials() { + super.eraseCredentials(); + } + +} diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/user/security/config/AuthProperties.java b/hz-pm-api/src/main/java/com/hz/pm/api/user/security/config/AuthProperties.java index 9319260..9102745 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/user/security/config/AuthProperties.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/user/security/config/AuthProperties.java @@ -32,7 +32,7 @@ public class AuthProperties { /** * 代登陆接口 */ - private String agentLoginUrl; + private String authCodeLoginUrl; private String mhLoginUrl; diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/user/security/config/WebSecurityConfig.java b/hz-pm-api/src/main/java/com/hz/pm/api/user/security/config/WebSecurityConfig.java index 8bfb598..802e023 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/user/security/config/WebSecurityConfig.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/user/security/config/WebSecurityConfig.java @@ -1,7 +1,7 @@ package com.hz.pm.api.user.security.config; import com.hz.pm.api.common.model.constant.CommonConst; -import com.hz.pm.api.user.security.auth.agent.AgentAuthSecurityConfig; +import com.hz.pm.api.user.security.auth.code.AuthCodeLoginSecurityConfig; import com.hz.pm.api.user.security.auth.credential.CredentialAuthSecurityConfig; import com.hz.pm.api.user.security.handler.DefaultExpiredSessionStrategy; import com.hz.pm.api.user.security.handler.DefaultLogoutSuccessHandler; @@ -31,7 +31,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { private final CredentialAuthSecurityConfig credentialAuthSecurityConfig; private final DefaultLogoutSuccessHandler logoutSuccessHandler; private final DefaultExpiredSessionStrategy defaultExpiredSessionStrategy; - private final AgentAuthSecurityConfig agentAuthSecurityConfig; + private final AuthCodeLoginSecurityConfig authCodeLoginSecurityConfig; private final MhAuthSecurityConfig mhAuthSecurityConfig; @Override @@ -40,7 +40,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { http.formLogin() .loginPage(authProperties.getAuthRequireUrl()) .and().apply(credentialAuthSecurityConfig) - .and().apply(agentAuthSecurityConfig) + .and().apply(authCodeLoginSecurityConfig) .and().apply(mhAuthSecurityConfig) .and() .authorizeRequests() diff --git a/hz-pm-api/src/main/resources/security/auth-dev.yml b/hz-pm-api/src/main/resources/security/auth-dev.yml index 388d764..2330d8d 100644 --- a/hz-pm-api/src/main/resources/security/auth-dev.yml +++ b/hz-pm-api/src/main/resources/security/auth-dev.yml @@ -3,7 +3,7 @@ security: auth-require-url: /api/v1/user/auth/auth-require invalid-session-url: /api/v1/user/auth/invalid-session password-login-url: /api/v1/user/auth/login - agent-login-url: /api/v1/user/auth/agent-login + auth-code-login-url: /api/v1/user/auth/authCodeLogin mh-login-url: /api/v1/user/auth/mh-login logout-url: /api/v1/user/auth/logout common-login-url: /api/v1/user/auth/common-login diff --git a/hz-pm-api/src/main/resources/security/auth-prod.yml b/hz-pm-api/src/main/resources/security/auth-prod.yml index ad39a58..2a672b5 100644 --- a/hz-pm-api/src/main/resources/security/auth-prod.yml +++ b/hz-pm-api/src/main/resources/security/auth-prod.yml @@ -3,7 +3,7 @@ security: auth-require-url: /api/v1/user/auth/auth-require invalid-session-url: /api/v1/user/auth/invalid-session password-login-url: /api/v1/user/auth/login - agent-login-url: /api/v1/user/auth/agent-login + auth-code-login-url: /api/v1/user/auth/authCodeLogin mh-login-url: /api/v1/user/auth/mh-login logout-url: /api/v1/user/auth/logout common-login-url: /api/v1/user/auth/common-login