Browse Source

Merge remote-tracking branch 'origin/master'

tags/24080901
WendyYang 1 year ago
parent
commit
7374c03523
12 changed files with 313 additions and 46 deletions
  1. +0
    -1
      pmapi/src/main/java/com/ningdatech/pmapi/common/handler/GlobalResponseHandler.java
  2. +2
    -1
      pmapi/src/main/java/com/ningdatech/pmapi/sms/manage/SmsManage.java
  3. +7
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/user/controller/UserAuthController.java
  4. +0
    -6
      pmapi/src/main/java/com/ningdatech/pmapi/user/controller/UserInfoController.java
  5. +5
    -38
      pmapi/src/main/java/com/ningdatech/pmapi/user/manage/UserInfoManage.java
  6. +5
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/user/security/auth/AuthProperties.java
  7. +74
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/user/security/auth/agent/AgentAuthFilter.java
  8. +40
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/user/security/auth/agent/AgentAuthProvider.java
  9. +55
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/user/security/auth/agent/AgentAuthSecurityConfig.java
  10. +76
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/user/security/auth/agent/AgentAuthToken.java
  11. +48
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/user/security/auth/agent/AgentLoginUserDetailService.java
  12. +1
    -0
      pmapi/src/main/resources/security/auth-dev.yml

+ 0
- 1
pmapi/src/main/java/com/ningdatech/pmapi/common/handler/GlobalResponseHandler.java View File

@@ -1,6 +1,5 @@
package com.ningdatech.pmapi.common.handler;

import cn.hutool.json.JSONUtil;
import com.ningdatech.basic.model.ApiResponse;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;


+ 2
- 1
pmapi/src/main/java/com/ningdatech/pmapi/sms/manage/SmsManage.java View File

@@ -23,6 +23,7 @@ import org.springframework.util.Assert;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Objects;

/**
* @author liuxinxin
@@ -81,7 +82,7 @@ public class SmsManage {

cachePlusOps.set(new CacheKey(cacheKey, Duration.ofMinutes(verificationCodeTypeEnum.getExpireTime())), cache);
String limitKey = SmsRedisKeyUtils.smsSendLimitKey(verificationCodeTypeEnum, request.getMobile());
if (StringUtils.isNotBlank(cachePlusOps.get(limitKey))) {
if (Objects.nonNull(cachePlusOps.get(limitKey))) {
long limitCount = cachePlusOps.incr(new CacheKey(limitKey, Duration.ofSeconds(DateUtil.restSecondsFromNowToNoon())));
// 超出单日发送次数之后直接锁定
if (limitCount >= verificationCodeTypeEnum.getSendTimesByDay().longValue()) {


+ 7
- 0
pmapi/src/main/java/com/ningdatech/pmapi/user/controller/UserAuthController.java View File

@@ -81,4 +81,11 @@ public class UserAuthController {
response.getWriter().write(objectMapper.writeValueAsString(BizConst.UNAUTHENTICATED));
}

@PostMapping(value = "/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", required = true) String userId) {
// 不实现任何内容,只是为了出api文档
}
}

+ 0
- 6
pmapi/src/main/java/com/ningdatech/pmapi/user/controller/UserInfoController.java View File

@@ -59,10 +59,4 @@ public class UserInfoController {
return userInfoManage.currentUserInfo();
}

@ApiOperation(value = "代登陆", notes = "代登陆")
@PostMapping("/generation-login")
public void generationLogin(@Valid @RequestBody ReqGenerationLoginPO reqGenerationLoginPO, HttpServletRequest httpServletRequest) {
userInfoManage.generationLogin(reqGenerationLoginPO);
}

}

+ 5
- 38
pmapi/src/main/java/com/ningdatech/pmapi/user/manage/UserInfoManage.java View File

@@ -17,7 +17,10 @@ import com.ningdatech.pmapi.sys.service.IRoleService;
import com.ningdatech.pmapi.sys.service.IUserRoleService;
import com.ningdatech.pmapi.user.constant.UserAvailableEnum;
import com.ningdatech.pmapi.user.entity.UserInfo;
import com.ningdatech.pmapi.user.model.po.*;
import com.ningdatech.pmapi.user.model.po.ReqUserDetailEditPO;
import com.ningdatech.pmapi.user.model.po.ReqUserDetailPO;
import com.ningdatech.pmapi.user.model.po.ReqUserDisableOrEnablePO;
import com.ningdatech.pmapi.user.model.po.ReqUserInfoListPO;
import com.ningdatech.pmapi.user.model.vo.ResUserDetailVO;
import com.ningdatech.pmapi.user.model.vo.ResUserInfoListVO;
import com.ningdatech.pmapi.user.model.vo.UserRoleVO;
@@ -25,7 +28,6 @@ import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO;
import com.ningdatech.pmapi.user.service.IUserInfoService;
import com.ningdatech.pmapi.user.util.LoginUserUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@@ -250,7 +252,7 @@ public class UserInfoManage {
}
resUserDetailVO.setUserRoleInfoList(userRoleInfoList);
UserFullInfoDTO userFullInfo = userInfoHelper.getUserFullInfo(userId);
if(Objects.nonNull(userFullInfo)){
if (Objects.nonNull(userFullInfo)) {
resUserDetailVO.setOrgCode(userFullInfo.getOrganizationCode());
resUserDetailVO.setOrgName(userFullInfo.getOrganizationName());
resUserDetailVO.setRegionCode(userFullInfo.getRegionCode());
@@ -258,39 +260,4 @@ public class UserInfoManage {
return resUserDetailVO;
}

public void generationLogin(ReqGenerationLoginPO reqGenerationLoginPO) {
Long userId = reqGenerationLoginPO.getUserId();
UserInfo userInfo = iUserInfoService.getById(userId);
if (Objects.isNull(userInfo)) {
throw new BizException("该员工账号处于禁用状态中,无法使用");
}
if (!UserAvailableEnum.ENABLE.name().equals(userInfo.getAvailable())) {
throw new BizException("该员工账号处于禁用状态中,无法使用");
}
UserFullInfoDTO userFullInfo = userInfoHelper.getUserFullInfo(userId);


// ReqGenerationLoginPO reqGenerationLoginPO
}

// public void autoLogin(Long userId){
// userDetailsService.loadUserByUsername(userId + UserDeatilsServiceConstant.USER_DETAILS_SERVICE_SEPARATOR + LoginTypeEnum.USERNAME_PASSWORD_LOGIN.name());
//
// CredentialAuthToken token = new CredentialAuthToken(email, password);
// try {
// token.setDetails(new WebAuthenticationDetails(httpServletRequest));
// UsernamePasswordAuthToken authenticatedUser = (UsernamePasswordAuthToken)usernamePasswordAuthSecurityConfig
// .getAuthenticationManager().authenticate(token);
// SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
// httpServletRequest.getSession().setAttribute(
// HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
// String sessionId = httpServletRequest.getSession().getId();
// putSessionIdToCache(LoginUserUtil.getUserId(), sessionId);
// } catch (
// AuthenticationException e) {
// throw new RuntimeException("autoLogIn Authentication failed!", e);
// }
// }


}

+ 5
- 0
pmapi/src/main/java/com/ningdatech/pmapi/user/security/auth/AuthProperties.java View File

@@ -29,6 +29,11 @@ public class AuthProperties {

private String passwordLoginUrl;

/**
* 代登陆接口
*/
private String agentLoginUrl;

private String logoutUrl;

private List<String> ignoreAuthUrls;


+ 74
- 0
pmapi/src/main/java/com/ningdatech/pmapi/user/security/auth/agent/AgentAuthFilter.java View File

@@ -0,0 +1,74 @@
package com.ningdatech.pmapi.user.security.auth.agent;

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;

/**
* @Author LiuXinXin
* @Date 2020/8/3 8:46 下午
* @Version 1.0
**/
public class AgentAuthFilter extends AbstractAuthenticationProcessingFilter {

private boolean postOnly = true;

private static final String USER_ID_PARAMETER = "userId";

// ~ Constructors
// ===================================================================================================

public AgentAuthFilter(String processingUrl) {
super(new AntPathRequestMatcher(processingUrl, HttpMethod.POST.name()));
}

// ~ Methods
// ========================================================================================================

@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
if (postOnly && !request.getMethod().equals(HttpMethod.POST.name())) {
throw new AuthenticationServiceException("请求方法错误");
}
String userId = request.getParameter(USER_ID_PARAMETER);
if (StringUtils.isBlank(userId)) {
throw new BadCredentialsException("用户id 不能为空");
}

userId = trim(userId);
try {
AgentAuthToken authRequest = new AgentAuthToken(userId, userId);
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
} catch (AuthenticationException e) {
throw new BadCredentialsException("账号或密码错误");
} catch (BizException e) {
throw new BadCredentialsException(e.getMessage());
} catch (Exception e) {
throw new InternalAuthenticationServiceException("授权失败:", e);
}
}

protected void setDetails(HttpServletRequest request, AgentAuthToken authRequest) {
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
}

private String trim(String trimStr) {
if (StringUtils.isNotBlank(trimStr)) {
return trimStr.trim();
}
return null;
}
}

+ 40
- 0
pmapi/src/main/java/com/ningdatech/pmapi/user/security/auth/agent/AgentAuthProvider.java View File

@@ -0,0 +1,40 @@
package com.ningdatech.pmapi.user.security.auth.agent;

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;

/**
* @Author LiuXinXin
* @Date 2020/8/3 8:55 下午
* @Version 1.0
**/
public class AgentAuthProvider implements AuthenticationProvider {

private UserDetailsService userDetailsService;

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
if (!(authentication instanceof AgentAuthToken)) {
throw new RuntimeException("CustomAuthProvider 只支持 CustomAuthToken");
}
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);
}

public void setUserDetailsService(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}

}

+ 55
- 0
pmapi/src/main/java/com/ningdatech/pmapi/user/security/auth/agent/AgentAuthSecurityConfig.java View File

@@ -0,0 +1,55 @@
package com.ningdatech.pmapi.user.security.auth.agent;

import com.ningdatech.pmapi.user.security.auth.AuthProperties;
import org.springframework.beans.factory.annotation.Autowired;
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;

/**
* 账号密码登陆的认证配置
*/
@Component
public class AgentAuthSecurityConfig
extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {

@Autowired
@Qualifier(value = "defaultLoginSuccessHandler")
protected AuthenticationSuccessHandler defaultLoginSuccessHandler;

@Autowired
@Qualifier(value = "defaultLoginFailureHandler")
protected AuthenticationFailureHandler defaultLoginFailureHandler;

@Autowired
@Qualifier(value = "agentLoginUserDetailService")
private UserDetailsService agentLoginUserDetailService;

@Autowired
private AuthProperties authProperties;

private AuthenticationManager authenticationManager;

@Override
public void configure(HttpSecurity http) throws Exception {
AgentAuthFilter agentAuthFilter =
new AgentAuthFilter(authProperties.getAgentLoginUrl());
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);
}
}

+ 76
- 0
pmapi/src/main/java/com/ningdatech/pmapi/user/security/auth/agent/AgentAuthToken.java View File

@@ -0,0 +1,76 @@
package com.ningdatech.pmapi.user.security.auth.agent;

import com.ningdatech.pmapi.user.constant.LoginTypeEnum;
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
* <code>UsernamePasswordAuthenticationToken</code>, as the {@link #isAuthenticated()} will return
* <code>false</code>.
*/
public AgentAuthToken(String principal, String credentials) {
super(null);
this.principal = principal;
this.credentials = credentials;
setAuthenticated(false);
}

/**
* This constructor should only be used by <code>AuthenticationManager</code> or <code>AuthenticationProvider</code>
* implementations that are satisfied with producing a trusted (i.e. {@link #isAuthenticated()} = <code>true</code>)
* authentication token.
*
* @param principal
* @param authorities
*/
public AgentAuthToken(Object principal, Object credentials,
Collection<? extends GrantedAuthority> 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();
}

}

+ 48
- 0
pmapi/src/main/java/com/ningdatech/pmapi/user/security/auth/agent/AgentLoginUserDetailService.java View File

@@ -0,0 +1,48 @@
package com.ningdatech.pmapi.user.security.auth.agent;


import com.ningdatech.pmapi.user.manage.UserAuthLoginManage;
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO;
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails;
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 UserAuthLoginManage userAuthLoginManage;

@Override
public UserInfoDetails loadUserByUsername(String username) throws UsernameNotFoundException {

final Long userId = Long.parseLong(username);

UserFullInfoDTO userFullInfoDTO = userAuthLoginManage.getUserFullInfo(userId);

if (Objects.isNull(userFullInfoDTO)) {
throw new UsernameNotFoundException(String.format("%s user not exist", username));
}
UserInfoDetails userInfoDetails = new UserInfoDetails();
userInfoDetails.setUserId(userFullInfoDTO.getUserId());
userInfoDetails.setUsername(userFullInfoDTO.getUsername());
userInfoDetails.setRealName(userFullInfoDTO.getRealName());
userInfoDetails.setUserRoleList(userFullInfoDTO.getUserRoleList());
userInfoDetails.setRegionCode(userFullInfoDTO.getRegionCode());
userInfoDetails.setIdentifier(userFullInfoDTO.getIdentifier());
userInfoDetails.setPassword(userFullInfoDTO.getCredential());

userInfoDetails.setOrganizationCode(userFullInfoDTO.getOrganizationCode());
userInfoDetails.setOrganizationName(userFullInfoDTO.getOrganizationName());
return userInfoDetails;
}
}

+ 1
- 0
pmapi/src/main/resources/security/auth-dev.yml View File

@@ -3,6 +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
logout-url: /api/v1/user/auth/logout
ignore-auth-urls:
- /v2/api-docs


Loading…
Cancel
Save