mirror of
http://git.pig4cloud.com/pig/pigx.git
synced 2026-11-08 12:39:05 +08:00
♻️ 增加 NoToken 注解方便对应 无token feign调用场景
This commit is contained in:
1 parent
a7552c6a5c
commit
13f13d4813
27 files changed
+440
-335
No files matched your search
+5
-13
@@ -20,14 +20,12 @@
|
||||
package com.pig4cloud.pigx.app.api.feign;
|
||||
|
||||
import com.pig4cloud.pigx.app.api.dto.AppUserInfo;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.ServiceNameConstants;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.feign.annotation.NoToken;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
@@ -42,8 +40,9 @@ public interface RemoteAppUserService {
|
||||
* @param from 调用标志
|
||||
* @return R
|
||||
*/
|
||||
@NoToken
|
||||
@GetMapping("/appuser/info/{username}")
|
||||
R<AppUserInfo> info(@PathVariable("username") String username, @RequestHeader(SecurityConstants.FROM) String from);
|
||||
R<AppUserInfo> info(@PathVariable("username") String username);
|
||||
|
||||
/**
|
||||
* 通过社交账号或手机号查询用户、角色信息
|
||||
@@ -51,16 +50,9 @@ public interface RemoteAppUserService {
|
||||
* @param from 调用标志
|
||||
* @return
|
||||
*/
|
||||
@NoToken
|
||||
@GetMapping("/appsocial/info/{inStr}")
|
||||
R<AppUserInfo> social(@PathVariable("inStr") String inStr, @RequestHeader(SecurityConstants.FROM) String from);
|
||||
R<AppUserInfo> social(@PathVariable("inStr") String inStr);
|
||||
|
||||
/**
|
||||
* 锁定用户
|
||||
* @param username 用户名
|
||||
* @param from 调用标识
|
||||
* @return
|
||||
*/
|
||||
@PutMapping("/appuser/lock/{username}")
|
||||
R<Boolean> lockUser(@PathVariable("username") String username, @RequestHeader(SecurityConstants.FROM) String from);
|
||||
|
||||
}
|
||||
@@ -38,6 +38,8 @@ import com.pig4cloud.pigx.common.security.annotation.Inner;
|
||||
import com.pig4cloud.pigx.common.security.service.PigxUser;
|
||||
import com.pig4cloud.pigx.common.security.util.OAuth2ErrorCodesExpand;
|
||||
import com.pig4cloud.pigx.common.security.util.OAuthClientException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -59,8 +61,6 @@ import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.security.Principal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -103,7 +103,7 @@ public class PigxTokenEndpoint {
|
||||
modelAndView.setViewName("ftl/login");
|
||||
modelAndView.addObject("error", error);
|
||||
|
||||
R<List<SysTenant>> tenantList = tenantService.list(SecurityConstants.FROM_IN);
|
||||
R<List<SysTenant>> tenantList = tenantService.list();
|
||||
modelAndView.addObject("tenantList", tenantList.getData());
|
||||
return modelAndView;
|
||||
}
|
||||
@@ -114,8 +114,9 @@ public class PigxTokenEndpoint {
|
||||
@RequestParam(OAuth2ParameterNames.SCOPE) String scope,
|
||||
@RequestParam(OAuth2ParameterNames.STATE) String state) {
|
||||
SysOauthClientDetails clientDetails = RetOps
|
||||
.of(clientDetailsService.getClientDetailsById(clientId, SecurityConstants.FROM_IN)).getData()
|
||||
.orElseThrow(() -> new OAuthClientException("clientId 不合法"));
|
||||
.of(clientDetailsService.getClientDetailsById(clientId))
|
||||
.getData()
|
||||
.orElseThrow(() -> new OAuthClientException("clientId 不合法"));
|
||||
|
||||
Set<String> authorizedScopes = StringUtils.commaDelimitedListToSet(clientDetails.getScope());
|
||||
modelAndView.addObject("clientId", clientId);
|
||||
|
||||
+94
-94
@@ -29,6 +29,8 @@ import com.pig4cloud.pigx.common.data.resolver.ParamResolver;
|
||||
import com.pig4cloud.pigx.common.log.event.SysLogEvent;
|
||||
import com.pig4cloud.pigx.common.log.util.LogTypeEnum;
|
||||
import com.pig4cloud.pigx.common.log.util.SysLogUtils;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -45,8 +47,6 @@ import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
|
||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -59,114 +59,114 @@ import java.util.concurrent.TimeUnit;
|
||||
@RequiredArgsConstructor
|
||||
public class PigxAuthenticationFailureEventHandler implements AuthenticationFailureHandler {
|
||||
|
||||
private static final MappingJackson2HttpMessageConverter errorHttpResponseConverter = new MappingJackson2HttpMessageConverter();
|
||||
private static final MappingJackson2HttpMessageConverter errorHttpResponseConverter = new MappingJackson2HttpMessageConverter();
|
||||
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
|
||||
private final ApplicationEventPublisher publisher;
|
||||
private final ApplicationEventPublisher publisher;
|
||||
|
||||
private final KeyStrResolver tenantKeyStrResolver;
|
||||
private final KeyStrResolver tenantKeyStrResolver;
|
||||
|
||||
private final RemoteUserService userService;
|
||||
private final RemoteUserService userService;
|
||||
|
||||
/**
|
||||
* Called when an authentication attempt fails.
|
||||
*
|
||||
* @param request the request during which the authentication attempt occurred.
|
||||
* @param response the response.
|
||||
* @param exception the exception which was thrown to reject the authentication
|
||||
* request.
|
||||
*/
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException exception) {
|
||||
String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE);
|
||||
log.info("登录失败,异常:{}", exception.getLocalizedMessage());
|
||||
/**
|
||||
* Called when an authentication attempt fails.
|
||||
* @param request the request during which the authentication attempt occurred.
|
||||
* @param response the response.
|
||||
* @param exception the exception which was thrown to reject the authentication
|
||||
* request.
|
||||
*/
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException exception) {
|
||||
String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE);
|
||||
log.info("登录失败,异常:{}", exception.getLocalizedMessage());
|
||||
|
||||
// 密码模式记录错误信息
|
||||
if (OAuth2ParameterNames.PASSWORD.equals(grantType)) {
|
||||
String username = request.getParameter(OAuth2ParameterNames.USERNAME);
|
||||
// 密码模式记录错误信息
|
||||
if (OAuth2ParameterNames.PASSWORD.equals(grantType)) {
|
||||
String username = request.getParameter(OAuth2ParameterNames.USERNAME);
|
||||
|
||||
// 密码错误记录错误次数 (TOC用户不记录)
|
||||
String header = WebUtils.getRequest().getHeader(SecurityConstants.HEADER_TOC);
|
||||
if (exception instanceof OAuth2AuthenticationException
|
||||
&& !SecurityConstants.HEADER_TOC_YES.equals(header)) {
|
||||
recordLoginFailureTimes(username);
|
||||
}
|
||||
// 密码错误记录错误次数 (TOC用户不记录)
|
||||
String header = WebUtils.getRequest().getHeader(SecurityConstants.HEADER_TOC);
|
||||
if (exception instanceof OAuth2AuthenticationException
|
||||
&& !SecurityConstants.HEADER_TOC_YES.equals(header)) {
|
||||
recordLoginFailureTimes(username);
|
||||
}
|
||||
|
||||
// 记录登录失败错误信息
|
||||
sendFailureEventLog(request, exception, username);
|
||||
}
|
||||
// 记录登录失败错误信息
|
||||
sendFailureEventLog(request, exception, username);
|
||||
}
|
||||
|
||||
// 写出错误信息
|
||||
sendErrorResponse(request, response, exception);
|
||||
}
|
||||
// 写出错误信息
|
||||
sendErrorResponse(request, response, exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录失败日志
|
||||
*
|
||||
* @param request HttpServletRequest
|
||||
* @param exception 错误日志
|
||||
* @param username 用户名
|
||||
*/
|
||||
private void sendFailureEventLog(HttpServletRequest request, AuthenticationException exception, String username) {
|
||||
SysLogDTO logVo = SysLogUtils.getSysLog();
|
||||
logVo.setTitle("登录失败");
|
||||
logVo.setLogType(LogTypeEnum.ERROR.getType());
|
||||
logVo.setException(exception.getLocalizedMessage());
|
||||
// 发送异步日志事件
|
||||
String startTimeStr = request.getHeader(CommonConstants.REQUEST_START_TIME);
|
||||
if (StrUtil.isNotBlank(startTimeStr)) {
|
||||
Long startTime = Long.parseLong(startTimeStr);
|
||||
Long endTime = System.currentTimeMillis();
|
||||
logVo.setTime(endTime - startTime);
|
||||
}
|
||||
String header = request.getHeader(HttpHeaders.AUTHORIZATION);
|
||||
String clientId = WebUtils.extractClientId(header).orElse(null);
|
||||
logVo.setServiceId(clientId);
|
||||
logVo.setCreateBy(username);
|
||||
logVo.setTenantId(Long.parseLong(tenantKeyStrResolver.key()));
|
||||
publisher.publishEvent(new SysLogEvent(logVo));
|
||||
}
|
||||
/**
|
||||
* 记录失败日志
|
||||
* @param request HttpServletRequest
|
||||
* @param exception 错误日志
|
||||
* @param username 用户名
|
||||
*/
|
||||
private void sendFailureEventLog(HttpServletRequest request, AuthenticationException exception, String username) {
|
||||
SysLogDTO logVo = SysLogUtils.getSysLog();
|
||||
logVo.setTitle("登录失败");
|
||||
logVo.setLogType(LogTypeEnum.ERROR.getType());
|
||||
logVo.setException(exception.getLocalizedMessage());
|
||||
// 发送异步日志事件
|
||||
String startTimeStr = request.getHeader(CommonConstants.REQUEST_START_TIME);
|
||||
if (StrUtil.isNotBlank(startTimeStr)) {
|
||||
Long startTime = Long.parseLong(startTimeStr);
|
||||
Long endTime = System.currentTimeMillis();
|
||||
logVo.setTime(endTime - startTime);
|
||||
}
|
||||
String header = request.getHeader(HttpHeaders.AUTHORIZATION);
|
||||
String clientId = WebUtils.extractClientId(header).orElse(null);
|
||||
logVo.setServiceId(clientId);
|
||||
logVo.setCreateBy(username);
|
||||
logVo.setTenantId(Long.parseLong(tenantKeyStrResolver.key()));
|
||||
publisher.publishEvent(new SysLogEvent(logVo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录登录失败此处,如果操作阈值 调用接口锁定用户
|
||||
*
|
||||
* @param username username
|
||||
*/
|
||||
private void recordLoginFailureTimes(String username) {
|
||||
String key = String.format("%s:%s:%s", tenantKeyStrResolver.key(), CacheConstants.LOGIN_ERROR_TIMES, username);
|
||||
Long deltaTimes = ParamResolver.getLong("LOGIN_ERROR_TIMES", 5L);
|
||||
Long times = redisTemplate.opsForValue().increment(key);
|
||||
/**
|
||||
* 记录登录失败此处,如果操作阈值 调用接口锁定用户
|
||||
* @param username username
|
||||
*/
|
||||
private void recordLoginFailureTimes(String username) {
|
||||
String key = String.format("%s:%s:%s", tenantKeyStrResolver.key(), CacheConstants.LOGIN_ERROR_TIMES, username);
|
||||
Long deltaTimes = ParamResolver.getLong("LOGIN_ERROR_TIMES", 5L);
|
||||
Long times = redisTemplate.opsForValue().increment(key);
|
||||
|
||||
// 自动过期时间
|
||||
Long deltaTime = ParamResolver.getLong("DELTA_TIME", 1L);
|
||||
redisTemplate.expire(key, deltaTime, TimeUnit.HOURS);
|
||||
// 自动过期时间
|
||||
Long deltaTime = ParamResolver.getLong("DELTA_TIME", 1L);
|
||||
redisTemplate.expire(key, deltaTime, TimeUnit.HOURS);
|
||||
|
||||
if (deltaTimes <= times) {
|
||||
userService.lockUser(username, SecurityConstants.FROM_IN);
|
||||
}
|
||||
}
|
||||
if (deltaTimes <= times) {
|
||||
userService.lockUser(username);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendErrorResponse(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException exception) throws IOException {
|
||||
ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
|
||||
httpResponse.setStatusCode(HttpStatus.UNAUTHORIZED);
|
||||
String errorMessage;
|
||||
private void sendErrorResponse(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException exception) throws IOException {
|
||||
ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
|
||||
httpResponse.setStatusCode(HttpStatus.UNAUTHORIZED);
|
||||
String errorMessage;
|
||||
|
||||
if (exception instanceof OAuth2AuthenticationException) {
|
||||
OAuth2AuthenticationException authorizationException = (OAuth2AuthenticationException) exception;
|
||||
errorMessage = StrUtil.isBlank(authorizationException.getError().getDescription())
|
||||
? authorizationException.getError().getErrorCode()
|
||||
: authorizationException.getError().getDescription();
|
||||
if (exception instanceof OAuth2AuthenticationException) {
|
||||
OAuth2AuthenticationException authorizationException = (OAuth2AuthenticationException) exception;
|
||||
errorMessage = StrUtil.isBlank(authorizationException.getError().getDescription())
|
||||
? authorizationException.getError().getErrorCode()
|
||||
: authorizationException.getError().getDescription();
|
||||
|
||||
this.errorHttpResponseConverter.write(R.failed(authorizationException.getError().getErrorCode(), errorMessage), MediaType.APPLICATION_JSON, httpResponse);
|
||||
this.errorHttpResponseConverter.write(
|
||||
R.failed(authorizationException.getError().getErrorCode(), errorMessage),
|
||||
MediaType.APPLICATION_JSON, httpResponse);
|
||||
|
||||
} else {
|
||||
errorMessage = exception.getLocalizedMessage();
|
||||
this.errorHttpResponseConverter.write(R.failed(errorMessage), MediaType.APPLICATION_JSON, httpResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
errorMessage = exception.getLocalizedMessage();
|
||||
this.errorHttpResponseConverter.write(R.failed(errorMessage), MediaType.APPLICATION_JSON, httpResponse);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -77,7 +77,7 @@ public class DefaultAuditLogHandle implements IAuditLogHandle {
|
||||
|
||||
@Async
|
||||
public void asyncSend(List<SysAuditLog> auditLogList) {
|
||||
remoteLogService.saveLog(auditLogList, SecurityConstants.FROM_IN);
|
||||
remoteLogService.saveLog(auditLogList);
|
||||
}
|
||||
|
||||
}
|
||||
+2
-3
@@ -3,7 +3,6 @@ package com.pig4cloud.pigx.common.data.resolver;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.pig4cloud.pigx.admin.api.feign.RemoteParamService;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
@@ -31,7 +30,7 @@ public class ParamResolver {
|
||||
}
|
||||
|
||||
RemoteParamService remoteParamService = SpringContextHolder.getBean(RemoteParamService.class);
|
||||
return remoteParamService.getByKeys(key, SecurityConstants.FROM_IN).getData();
|
||||
return remoteParamService.getByKeys(key).getData();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,7 +61,7 @@ public class ParamResolver {
|
||||
|
||||
RemoteParamService remoteParamService = SpringContextHolder.getBean(RemoteParamService.class);
|
||||
|
||||
String result = remoteParamService.getByKey(key, SecurityConstants.FROM_IN).getData();
|
||||
String result = remoteParamService.getByKey(key).getData();
|
||||
|
||||
if (StrUtil.isNotBlank(result)) {
|
||||
return Convert.convert(clazz, result);
|
||||
|
||||
@@ -28,5 +28,10 @@
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
||||
</dependency>
|
||||
<!-- 基础依赖 -->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-core</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
+32
-6
@@ -18,6 +18,8 @@
|
||||
package com.pig4cloud.pigx.common.feign;
|
||||
|
||||
import com.pig4cloud.pigx.common.feign.endpoint.FeignClientEndpoint;
|
||||
import com.pig4cloud.pigx.common.feign.interceptor.PigxFeignInnerRequestInterceptor;
|
||||
import com.pig4cloud.pigx.common.feign.interceptor.PigxFeignRequestCloseInterceptor;
|
||||
import feign.Feign;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
@@ -42,11 +44,35 @@ import org.springframework.context.annotation.Import;
|
||||
@AutoConfigureAfter(EnableFeignClients.class)
|
||||
public class PigxFeignAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnAvailableEndpoint
|
||||
public FeignClientEndpoint feignClientEndpoint(ApplicationContext context) {
|
||||
return new FeignClientEndpoint(context);
|
||||
}
|
||||
/**
|
||||
* feign actuator endpoint
|
||||
* @param context
|
||||
* @return FeignClientEndpoint
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnAvailableEndpoint
|
||||
public FeignClientEndpoint feignClientEndpoint(ApplicationContext context) {
|
||||
return new FeignClientEndpoint(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* add http connection close header
|
||||
*
|
||||
* @return PigxFeignRequestCloseInterceptor
|
||||
*/
|
||||
@Bean
|
||||
public PigxFeignRequestCloseInterceptor pigFeignRequestCloseInterceptor() {
|
||||
return new PigxFeignRequestCloseInterceptor();
|
||||
}
|
||||
|
||||
/**
|
||||
* add inner request header
|
||||
*
|
||||
* @return PigxFeignInnerRequestInterceptor
|
||||
*/
|
||||
@Bean
|
||||
public PigxFeignInnerRequestInterceptor pigFeignInnerRequestInterceptor() {
|
||||
return new PigxFeignInnerRequestInterceptor();
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.pig4cloud.pigx.common.feign.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 服务无token调用声明注解
|
||||
* <p>
|
||||
* 只有发起方没有 token 时候才需要添加此注解, @NoToken + @Inner
|
||||
* <p>
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface NoToken {
|
||||
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package com.pig4cloud.pigx.common.feign.interceptor;
|
||||
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.feign.annotation.NoToken;
|
||||
import feign.RequestInterceptor;
|
||||
import feign.RequestTemplate;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2024/6/1
|
||||
*/
|
||||
public class PigxFeignInnerRequestInterceptor implements RequestInterceptor, Ordered {
|
||||
|
||||
/**
|
||||
* Called for every request. Add data using methods on the supplied
|
||||
* {@link RequestTemplate}.
|
||||
* @param template
|
||||
*/
|
||||
@Override
|
||||
public void apply(RequestTemplate template) {
|
||||
Method method = template.methodMetadata().method();
|
||||
NoToken noToken = method.getAnnotation(NoToken.class);
|
||||
if (noToken != null) {
|
||||
template.header(SecurityConstants.FROM, SecurityConstants.FROM_IN);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.pig4cloud.pigx.common.feign.interceptor;
|
||||
|
||||
import feign.RequestInterceptor;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2024/3/15
|
||||
* <p>
|
||||
* http connection close
|
||||
*/
|
||||
public class PigxFeignRequestCloseInterceptor implements RequestInterceptor {
|
||||
|
||||
/**
|
||||
* set connection close
|
||||
* @param template
|
||||
*/
|
||||
@Override
|
||||
public void apply(feign.RequestTemplate template) {
|
||||
template.header(HttpHeaders.CONNECTION, "close");
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -88,7 +88,7 @@ public class SysLogListener implements InitializingBean {
|
||||
}
|
||||
|
||||
source.setBody(null);
|
||||
remoteLogService.saveLog(source, SecurityConstants.FROM_IN);
|
||||
remoteLogService.saveLog(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-2
@@ -20,7 +20,6 @@ package com.pig4cloud.pigx.common.security.service;
|
||||
import com.pig4cloud.pigx.admin.api.dto.UserInfo;
|
||||
import com.pig4cloud.pigx.admin.api.feign.RemoteUserService;
|
||||
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.enums.UserTypeEnum;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -60,7 +59,7 @@ public class PigxDefaultUserDetailsServiceImpl implements PigxUserDetailsService
|
||||
return cache.get(username, PigxUser.class);
|
||||
}
|
||||
|
||||
R<UserInfo> result = remoteUserService.info(username, SecurityConstants.FROM_IN);
|
||||
R<UserInfo> result = remoteUserService.info(username);
|
||||
UserDetails userDetails = getUserDetails(result);
|
||||
cache.put(username, userDetails);
|
||||
return userDetails;
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ public class PigxMobileUserDetailServiceImpl implements PigxUserDetailsService {
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public UserDetails loadUserByUsername(String phone) {
|
||||
R<UserInfo> result = remoteUserService.social(phone, SecurityConstants.FROM_IN);
|
||||
R<UserInfo> result = remoteUserService.social(phone);
|
||||
return getUserDetails(result);
|
||||
}
|
||||
|
||||
|
||||
+31
-24
@@ -88,46 +88,53 @@ public class PigxRemoteRegisteredClientRepository implements RegisteredClientRep
|
||||
public RegisteredClient findByClientId(String clientId) {
|
||||
|
||||
SysOauthClientDetails clientDetails = RetOps
|
||||
.of(clientDetailsService.getClientDetailsById(clientId, SecurityConstants.FROM_IN)).getData()
|
||||
.orElseThrow(() -> new OAuth2AuthorizationCodeRequestAuthenticationException(
|
||||
new OAuth2Error("客户端查询异常,请检查数据库链接"), null));
|
||||
.of(clientDetailsService.getClientDetailsById(clientId))
|
||||
.getData()
|
||||
.orElseThrow(() -> new OAuth2AuthorizationCodeRequestAuthenticationException(
|
||||
new OAuth2Error("客户端查询异常,请检查数据库链接"), null));
|
||||
|
||||
RegisteredClient.Builder builder = RegisteredClient.withId(clientDetails.getClientId())
|
||||
.clientId(clientDetails.getClientId())
|
||||
.clientSecret(SecurityConstants.NOOP + clientDetails.getClientSecret())
|
||||
.clientAuthenticationMethods(clientAuthenticationMethods -> {
|
||||
clientAuthenticationMethods.add(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
|
||||
clientAuthenticationMethods.add(ClientAuthenticationMethod.CLIENT_SECRET_POST);
|
||||
});
|
||||
.clientId(clientDetails.getClientId())
|
||||
.clientSecret(SecurityConstants.NOOP + clientDetails.getClientSecret())
|
||||
.clientAuthenticationMethods(clientAuthenticationMethods -> {
|
||||
clientAuthenticationMethods.add(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
|
||||
clientAuthenticationMethods.add(ClientAuthenticationMethod.CLIENT_SECRET_POST);
|
||||
});
|
||||
// 授权模式
|
||||
Arrays.stream(clientDetails.getAuthorizedGrantTypes())
|
||||
.forEach(grant -> builder.authorizationGrantType(new AuthorizationGrantType(grant)));
|
||||
.forEach(grant -> builder.authorizationGrantType(new AuthorizationGrantType(grant)));
|
||||
|
||||
// 回调地址
|
||||
Optional.ofNullable(clientDetails.getWebServerRedirectUri()).ifPresent(redirectUri -> Arrays
|
||||
.stream(redirectUri.split(StrUtil.COMMA)).filter(StrUtil::isNotBlank).forEach(builder::redirectUri));
|
||||
Optional.ofNullable(clientDetails.getWebServerRedirectUri())
|
||||
.ifPresent(redirectUri -> Arrays.stream(redirectUri.split(StrUtil.COMMA))
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.forEach(builder::redirectUri));
|
||||
|
||||
// scope
|
||||
Optional.ofNullable(clientDetails.getScope()).ifPresent(
|
||||
scope -> Arrays.stream(scope.split(StrUtil.COMMA)).filter(StrUtil::isNotBlank).forEach(builder::scope));
|
||||
Optional.ofNullable(clientDetails.getScope())
|
||||
.ifPresent(scope -> Arrays.stream(scope.split(StrUtil.COMMA))
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.forEach(builder::scope));
|
||||
|
||||
// 注入扩展配置
|
||||
Optional.ofNullable(clientDetails.getAdditionalInformation()).ifPresent(ext -> {
|
||||
Map map = JSONUtil.parseObj(ext).toBean(Map.class);
|
||||
builder.clientSettings(ClientSettings.withSettings(map).requireProofKey(false)
|
||||
.requireAuthorizationConsent(!BooleanUtil.toBoolean(clientDetails.getAutoapprove())).build());
|
||||
builder.clientSettings(ClientSettings.withSettings(map)
|
||||
.requireProofKey(false)
|
||||
.requireAuthorizationConsent(!BooleanUtil.toBoolean(clientDetails.getAutoapprove()))
|
||||
.build());
|
||||
});
|
||||
|
||||
return builder
|
||||
.tokenSettings(TokenSettings.builder().accessTokenFormat(OAuth2TokenFormat.REFERENCE)
|
||||
.accessTokenTimeToLive(Duration.ofSeconds(Optional
|
||||
.ofNullable(clientDetails.getAccessTokenValidity()).orElse(accessTokenValiditySeconds)))
|
||||
.refreshTokenTimeToLive(
|
||||
Duration.ofSeconds(Optional.ofNullable(clientDetails.getRefreshTokenValidity())
|
||||
.orElse(refreshTokenValiditySeconds)))
|
||||
.build())
|
||||
.tokenSettings(TokenSettings.builder()
|
||||
.accessTokenFormat(OAuth2TokenFormat.REFERENCE)
|
||||
.accessTokenTimeToLive(Duration.ofSeconds(
|
||||
Optional.ofNullable(clientDetails.getAccessTokenValidity()).orElse(accessTokenValiditySeconds)))
|
||||
.refreshTokenTimeToLive(Duration.ofSeconds(Optional.ofNullable(clientDetails.getRefreshTokenValidity())
|
||||
.orElse(refreshTokenValiditySeconds)))
|
||||
.build())
|
||||
|
||||
.build();
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
|
||||
+10
-2
@@ -36,6 +36,9 @@ import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
|
||||
import org.springframework.security.oauth2.core.OAuth2Error;
|
||||
import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -68,7 +71,8 @@ public class PigxTocDefaultUserDetailsServiceImpl implements PigxUserDetailsServ
|
||||
if (cache != null && cache.get(username) != null) {
|
||||
return cache.get(username, PigxUser.class);
|
||||
}
|
||||
R<AppUserInfo> info = remoteAppUserServiceOptional.get().info(username, SecurityConstants.FROM_IN);
|
||||
|
||||
R<AppUserInfo> info = remoteAppUserServiceOptional.get().info(username);
|
||||
UserDetails userDetailsAppUser = this.getUserDetailsAppUser(info);
|
||||
if (cache != null) {
|
||||
cache.put(username, userDetailsAppUser);
|
||||
@@ -84,6 +88,7 @@ public class PigxTocDefaultUserDetailsServiceImpl implements PigxUserDetailsServ
|
||||
UserDetails getUserDetailsAppUser(R<AppUserInfo> result) {
|
||||
// @formatter:off
|
||||
return RetOps.of(result)
|
||||
.assertSuccess(r -> new OAuth2AuthenticationException(new OAuth2Error(OAuth2ErrorCodes.SERVER_ERROR, "用户信息获取失败",null)))
|
||||
.getData()
|
||||
.map(this::convertUserDetailsAppUser)
|
||||
.orElseThrow(() -> new UsernameNotFoundException("用户不存在"));
|
||||
@@ -105,7 +110,7 @@ public class PigxTocDefaultUserDetailsServiceImpl implements PigxUserDetailsServ
|
||||
|
||||
}
|
||||
Collection<? extends GrantedAuthority> authorities = AuthorityUtils
|
||||
.createAuthorityList(dbAuthsSet.toArray(new String[0]));
|
||||
.createAuthorityList(dbAuthsSet.toArray(new String[0]));
|
||||
AppUser user = info.getAppUser();
|
||||
// 构造security用户
|
||||
|
||||
@@ -128,6 +133,9 @@ public class PigxTocDefaultUserDetailsServiceImpl implements PigxUserDetailsServ
|
||||
*/
|
||||
@Override
|
||||
public boolean support(String clientId, String grantType) {
|
||||
if (Objects.isNull(WebUtils.getRequest())) {
|
||||
return false;
|
||||
}
|
||||
String header = WebUtils.getRequest().getHeader(SecurityConstants.HEADER_TOC);
|
||||
return SecurityConstants.HEADER_TOC_YES.equals(header);
|
||||
}
|
||||
|
||||
+74
-60
@@ -33,6 +33,9 @@ import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
|
||||
import org.springframework.security.oauth2.core.OAuth2Error;
|
||||
import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -45,74 +48,85 @@ import java.util.*;
|
||||
@RequiredArgsConstructor
|
||||
public class PigxTocMobileUserDetailsServiceImpl implements PigxUserDetailsService {
|
||||
|
||||
private final Optional<RemoteAppUserService> remoteAppUserServiceOptional;
|
||||
private final Optional<RemoteAppUserService> remoteAppUserServiceOptional;
|
||||
|
||||
/**
|
||||
* 用户密码登录
|
||||
* @param phone 用户密码登录
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public UserDetails loadUserByUsername(String phone) {
|
||||
if (!remoteAppUserServiceOptional.isPresent()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
R<AppUserInfo> info = remoteAppUserServiceOptional.get().social(phone, SecurityConstants.FROM_IN);
|
||||
return this.getUserDetailsAppUser(info);
|
||||
}
|
||||
/**
|
||||
* 用户密码登录
|
||||
*
|
||||
* @param phone 用户密码登录
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public UserDetails loadUserByUsername(String phone) {
|
||||
if (!remoteAppUserServiceOptional.isPresent()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
R<AppUserInfo> info = remoteAppUserServiceOptional.get().social(phone);
|
||||
return this.getUserDetailsAppUser(info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUser(PigxUser pigxUser) {
|
||||
return pigxUser;
|
||||
}
|
||||
@Override
|
||||
public UserDetails loadUserByUser(PigxUser pigxUser) {
|
||||
return pigxUser;
|
||||
}
|
||||
|
||||
UserDetails getUserDetailsAppUser(R<AppUserInfo> result) {
|
||||
// @formatter:off
|
||||
return RetOps.of(result).getData().map(this::convertUserDetailsAppUser).orElseThrow(() -> new UsernameNotFoundException("用户不存在"));
|
||||
UserDetails getUserDetailsAppUser(R<AppUserInfo> result) {
|
||||
// @formatter:off
|
||||
return RetOps.of(result)
|
||||
.assertSuccess(r -> new OAuth2AuthenticationException(new OAuth2Error(OAuth2ErrorCodes.SERVER_ERROR, "用户信息获取失败",null)))
|
||||
.getData()
|
||||
.map(this::convertUserDetailsAppUser)
|
||||
.orElseThrow(() -> new UsernameNotFoundException("用户不存在"));
|
||||
// @formatter:on
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* UserInfo 转 UserDetails
|
||||
* @param info
|
||||
* @return 返回UserDetails对象
|
||||
*/
|
||||
UserDetails convertUserDetailsAppUser(AppUserInfo info) {
|
||||
Set<String> dbAuthsSet = new HashSet<>();
|
||||
if (ArrayUtil.isNotEmpty(info.getRoles())) {
|
||||
// 获取角色
|
||||
Arrays.stream(info.getRoles()).forEach(roleId -> dbAuthsSet.add(SecurityConstants.ROLE + roleId));
|
||||
// 获取资源
|
||||
dbAuthsSet.addAll(Arrays.asList(info.getPermissions()));
|
||||
/**
|
||||
* UserInfo 转 UserDetails
|
||||
*
|
||||
* @param info
|
||||
* @return 返回UserDetails对象
|
||||
*/
|
||||
UserDetails convertUserDetailsAppUser(AppUserInfo info) {
|
||||
Set<String> dbAuthsSet = new HashSet<>();
|
||||
if (ArrayUtil.isNotEmpty(info.getRoles())) {
|
||||
// 获取角色
|
||||
Arrays.stream(info.getRoles()).forEach(roleId -> dbAuthsSet.add(SecurityConstants.ROLE + roleId));
|
||||
// 获取资源
|
||||
dbAuthsSet.addAll(Arrays.asList(info.getPermissions()));
|
||||
|
||||
}
|
||||
Collection<? extends GrantedAuthority> authorities = AuthorityUtils
|
||||
.createAuthorityList(dbAuthsSet.toArray(new String[0]));
|
||||
AppUser user = info.getAppUser();
|
||||
// 构造security用户
|
||||
}
|
||||
Collection<? extends GrantedAuthority> authorities = AuthorityUtils
|
||||
.createAuthorityList(dbAuthsSet.toArray(new String[0]));
|
||||
AppUser user = info.getAppUser();
|
||||
// 构造security用户
|
||||
|
||||
return new PigxUser(user.getUserId(), user.getUsername(), null, user.getPhone(), user.getAvatar(),
|
||||
user.getNickname(), user.getName(), user.getEmail(), user.getTenantId(),
|
||||
SecurityConstants.BCRYPT + user.getPassword(), true, true, UserTypeEnum.TOC.getStatus(), true,
|
||||
!CommonConstants.STATUS_LOCK.equals(user.getLockFlag()), authorities);
|
||||
}
|
||||
return new PigxUser(user.getUserId(), user.getUsername(), null, user.getPhone(), user.getAvatar(),
|
||||
user.getNickname(), user.getName(), user.getEmail(), user.getTenantId(),
|
||||
SecurityConstants.BCRYPT + user.getPassword(), true, true, UserTypeEnum.TOC.getStatus(), true,
|
||||
!CommonConstants.STATUS_LOCK.equals(user.getLockFlag()), authorities);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 15;
|
||||
}
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 15;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支持所有的 mobile 类型
|
||||
* @param clientId 目标客户端
|
||||
* @param grantType 授权类型
|
||||
* @return true/false
|
||||
*/
|
||||
@Override
|
||||
public boolean support(String clientId, String grantType) {
|
||||
String header = WebUtils.getRequest().getHeader(SecurityConstants.HEADER_TOC);
|
||||
return SecurityConstants.HEADER_TOC_YES.equals(header) && SecurityConstants.GRANT_MOBILE.equals(grantType);
|
||||
}
|
||||
/**
|
||||
* 支持所有的 mobile 类型
|
||||
*
|
||||
* @param clientId 目标客户端
|
||||
* @param grantType 授权类型
|
||||
* @return true/false
|
||||
*/
|
||||
@Override
|
||||
public boolean support(String clientId, String grantType) {
|
||||
if (Objects.isNull(WebUtils.getRequest())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String header = WebUtils.getRequest().getHeader(SecurityConstants.HEADER_TOC);
|
||||
return SecurityConstants.HEADER_TOC_YES.equals(header) && SecurityConstants.GRANT_MOBILE.equals(grantType);
|
||||
}
|
||||
|
||||
}
|
||||
+3
-4
@@ -20,13 +20,12 @@
|
||||
package com.pig4cloud.pigx.admin.api.feign;
|
||||
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysAuditLog;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.ServiceNameConstants;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.feign.annotation.NoToken;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -40,10 +39,10 @@ public interface RemoteAuditLogService {
|
||||
/**
|
||||
* 保存日志
|
||||
* @param auditLogList 日志实体 列表
|
||||
* @param from 是否内部调用
|
||||
* @return succes、false
|
||||
*/
|
||||
@NoToken
|
||||
@PostMapping("/audit")
|
||||
R<Boolean> saveLog(@RequestBody List<SysAuditLog> auditLogList, @RequestHeader(SecurityConstants.FROM) String from);
|
||||
R<Boolean> saveLog(@RequestBody List<SysAuditLog> auditLogList);
|
||||
|
||||
}
|
||||
+5
-7
@@ -20,13 +20,12 @@
|
||||
package com.pig4cloud.pigx.admin.api.feign;
|
||||
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysOauthClientDetails;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.ServiceNameConstants;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.feign.annotation.NoToken;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -40,19 +39,18 @@ public interface RemoteClientDetailsService {
|
||||
/**
|
||||
* 通过clientId 查询客户端信息
|
||||
* @param clientId 用户名
|
||||
* @param from 调用标志
|
||||
* @return R
|
||||
*/
|
||||
@NoToken
|
||||
@GetMapping("/client/getClientDetailsById/{clientId}")
|
||||
R<SysOauthClientDetails> getClientDetailsById(@PathVariable("clientId") String clientId,
|
||||
@RequestHeader(SecurityConstants.FROM) String from);
|
||||
R<SysOauthClientDetails> getClientDetailsById(@PathVariable("clientId") String clientId);
|
||||
|
||||
/**
|
||||
* 查询全部客户端
|
||||
* @param from 调用标识
|
||||
* @return R
|
||||
*/
|
||||
@NoToken
|
||||
@GetMapping("/client/list")
|
||||
R<List<SysOauthClientDetails>> listClientDetails(@RequestHeader(SecurityConstants.FROM) String from);
|
||||
R<List<SysOauthClientDetails>> listClientDetails();
|
||||
|
||||
}
|
||||
+3
-4
@@ -20,13 +20,12 @@
|
||||
package com.pig4cloud.pigx.admin.api.feign;
|
||||
|
||||
import com.pig4cloud.pigx.admin.api.dto.SysLogDTO;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.ServiceNameConstants;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.feign.annotation.NoToken;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
@@ -38,10 +37,10 @@ public interface RemoteLogService {
|
||||
/**
|
||||
* 保存日志
|
||||
* @param sysLog 日志实体
|
||||
* @param from 是否内部调用
|
||||
* @return succes、false
|
||||
*/
|
||||
@NoToken
|
||||
@PostMapping("/log/save")
|
||||
R<Boolean> saveLog(@RequestBody SysLogDTO sysLog, @RequestHeader(SecurityConstants.FROM) String from);
|
||||
R<Boolean> saveLog(@RequestBody SysLogDTO sysLog);
|
||||
|
||||
}
|
||||
+4
-7
@@ -1,12 +1,11 @@
|
||||
package com.pig4cloud.pigx.admin.api.feign;
|
||||
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.ServiceNameConstants;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.feign.annotation.NoToken;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -23,20 +22,18 @@ public interface RemoteParamService {
|
||||
/**
|
||||
* 通过key 查询参数配置
|
||||
* @param key key
|
||||
* @param from 声明成内部调用,避免MQ 等无法调用
|
||||
* @return
|
||||
*/
|
||||
@NoToken
|
||||
@GetMapping("/param/publicValue/{key}")
|
||||
R<String> getByKey(@PathVariable("key") String key, @RequestHeader(SecurityConstants.FROM) String from);
|
||||
R<String> getByKey(@PathVariable("key") String key);
|
||||
|
||||
/**
|
||||
* 通过keys 查询参数配置
|
||||
* @param keys keys
|
||||
* @param from 声明成内部调用,避免MQ 等无法调用
|
||||
* @return map
|
||||
*/
|
||||
@GetMapping("/param/publicValues")
|
||||
R<Map<String, Object>> getByKeys(@RequestParam("keys") String[] keys,
|
||||
@RequestHeader(SecurityConstants.FROM) String from);
|
||||
R<Map<String, Object>> getByKeys(@RequestParam("keys") String[] keys);
|
||||
|
||||
}
|
||||
+3
-4
@@ -20,12 +20,11 @@
|
||||
package com.pig4cloud.pigx.admin.api.feign;
|
||||
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysTenant;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.ServiceNameConstants;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.feign.annotation.NoToken;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -40,10 +39,10 @@ public interface RemoteTenantService {
|
||||
|
||||
/**
|
||||
* 查询全部有效租户
|
||||
* @param from 内部标志
|
||||
* @return
|
||||
*/
|
||||
@NoToken
|
||||
@GetMapping("/tenant/list")
|
||||
R<List<SysTenant>> list(@RequestHeader(SecurityConstants.FROM) String from);
|
||||
R<List<SysTenant>> list();
|
||||
|
||||
}
|
||||
+7
-10
@@ -19,9 +19,9 @@ package com.pig4cloud.pigx.admin.api.feign;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.ServiceNameConstants;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.feign.annotation.NoToken;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@@ -36,33 +36,30 @@ public interface RemoteTokenService {
|
||||
|
||||
/**
|
||||
* 分页查询token 信息
|
||||
* @param from 内部调用标志
|
||||
* @param params 分页参数
|
||||
* @param from 内部调用标志
|
||||
* @return page
|
||||
*/
|
||||
@NoToken
|
||||
@PostMapping("/token/page")
|
||||
R<Page> getTokenPage(@RequestBody Map<String, Object> params, @RequestHeader(SecurityConstants.FROM) String from);
|
||||
R<Page> getTokenPage(@RequestBody Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 删除token
|
||||
* @param from 内部调用标志
|
||||
* @param token token
|
||||
* @param from 内部调用标志
|
||||
* @return
|
||||
*/
|
||||
@NoToken
|
||||
@DeleteMapping("/token/{token}")
|
||||
R<Boolean> removeTokenById(@PathVariable("token") String token, @RequestHeader(SecurityConstants.FROM) String from);
|
||||
R<Boolean> removeTokenById(@PathVariable("token") String token);
|
||||
|
||||
/**
|
||||
* 校验令牌获取用户信息
|
||||
* @param token
|
||||
* @param from
|
||||
* @return
|
||||
*/
|
||||
@NoToken
|
||||
@GetMapping("/token/query-token")
|
||||
R<Map<String, Object>> queryToken(@RequestParam("token") String token,
|
||||
@RequestParam(CommonConstants.TENANT_ID) String tenantId,
|
||||
@RequestHeader(SecurityConstants.FROM) String from);
|
||||
@RequestParam(CommonConstants.TENANT_ID) String tenantId);
|
||||
|
||||
}
|
||||
+68
-76
@@ -22,9 +22,9 @@ package com.pig4cloud.pigx.admin.api.feign;
|
||||
import com.pig4cloud.pigx.admin.api.dto.UserDTO;
|
||||
import com.pig4cloud.pigx.admin.api.dto.UserInfo;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysUser;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.ServiceNameConstants;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.feign.annotation.NoToken;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@@ -37,88 +37,80 @@ import java.util.List;
|
||||
@FeignClient(contextId = "remoteUserService", value = ServiceNameConstants.UPMS_SERVICE)
|
||||
public interface RemoteUserService {
|
||||
|
||||
/**
|
||||
* 通过用户名查询用户、角色信息
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param from 调用标志
|
||||
* @return R
|
||||
*/
|
||||
@GetMapping("/user/info/{username}")
|
||||
R<UserInfo> info(@PathVariable("username") String username, @RequestHeader(SecurityConstants.FROM) String from);
|
||||
/**
|
||||
* 通过用户名查询用户、角色信息
|
||||
* @param username 用户名
|
||||
* @return R
|
||||
*/
|
||||
@NoToken
|
||||
@GetMapping("/user/info/{username}")
|
||||
R<UserInfo> info(@PathVariable("username") String username);
|
||||
|
||||
/**
|
||||
* 根据用户ID获取用户
|
||||
*
|
||||
* @param userId ID
|
||||
* @return SysUser
|
||||
*/
|
||||
@GetMapping("/user/details/{userId}")
|
||||
R<SysUser> getUserById(@PathVariable("userId") Long userId);
|
||||
/**
|
||||
* 根据用户ID获取用户
|
||||
* @param userId ID
|
||||
* @return SysUser
|
||||
*/
|
||||
@GetMapping("/user/details/{userId}")
|
||||
R<SysUser> getUserById(@PathVariable("userId") Long userId);
|
||||
|
||||
/**
|
||||
* 通过社交账号或手机号查询用户、角色信息
|
||||
*
|
||||
* @param inStr appid@code
|
||||
* @param from 调用标志
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/social/info/{inStr}")
|
||||
R<UserInfo> social(@PathVariable("inStr") String inStr, @RequestHeader(SecurityConstants.FROM) String from);
|
||||
/**
|
||||
* 通过社交账号或手机号查询用户、角色信息
|
||||
* @param inStr appid@code
|
||||
* @return
|
||||
*/
|
||||
@NoToken
|
||||
@GetMapping("/social/info/{inStr}")
|
||||
R<UserInfo> social(@PathVariable("inStr") String inStr);
|
||||
|
||||
/**
|
||||
* 查询上级部门的用户信息
|
||||
*
|
||||
* @param username 用户名
|
||||
* @return R
|
||||
*/
|
||||
@GetMapping("/user/ancestor/{username}")
|
||||
R<List<SysUser>> ancestorUsers(@PathVariable("username") String username);
|
||||
/**
|
||||
* 查询上级部门的用户信息
|
||||
* @param username 用户名
|
||||
* @return R
|
||||
*/
|
||||
@GetMapping("/user/ancestor/{username}")
|
||||
R<List<SysUser>> ancestorUsers(@PathVariable("username") String username);
|
||||
|
||||
/**
|
||||
* 锁定用户
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param from 调用标识
|
||||
* @return
|
||||
*/
|
||||
@PutMapping("/user/lock/{username}")
|
||||
R<Boolean> lockUser(@PathVariable("username") String username, @RequestHeader(SecurityConstants.FROM) String from);
|
||||
/**
|
||||
* 锁定用户
|
||||
* @param username 用户名
|
||||
* @return
|
||||
*/
|
||||
@NoToken
|
||||
@PutMapping("/user/lock/{username}")
|
||||
R<Boolean> lockUser(@PathVariable("username") String username);
|
||||
|
||||
/**
|
||||
* 根据角色ID查询用户列表
|
||||
*
|
||||
* @param roleIdList 角色ID列表
|
||||
* @return 用户ID列表
|
||||
*/
|
||||
@GetMapping("/user/getUserIdListByRoleIdList")
|
||||
R<List<Long>> getUserIdListByRoleIdList(@RequestParam("roleIdList") List<Long> roleIdList);
|
||||
/**
|
||||
* 根据角色ID查询用户列表
|
||||
* @param roleIdList 角色ID列表
|
||||
* @return 用户ID列表
|
||||
*/
|
||||
@GetMapping("/user/getUserIdListByRoleIdList")
|
||||
R<List<Long>> getUserIdListByRoleIdList(@RequestParam("roleIdList") List<Long> roleIdList);
|
||||
|
||||
/**
|
||||
* 根据部门ID列表获取用户ID列表接口
|
||||
*
|
||||
* @param deptIdList 部门ID列表
|
||||
* @return 用户ID列表
|
||||
*/
|
||||
@GetMapping("/user/getUserIdListByDeptIdList")
|
||||
R<List<SysUser>> getUserIdListByDeptIdList(@RequestParam("deptIdList") List<Long> deptIdList);
|
||||
/**
|
||||
* 根据部门ID列表获取用户ID列表接口
|
||||
* @param deptIdList 部门ID列表
|
||||
* @return 用户ID列表
|
||||
*/
|
||||
@GetMapping("/user/getUserIdListByDeptIdList")
|
||||
R<List<SysUser>> getUserIdListByDeptIdList(@RequestParam("deptIdList") List<Long> deptIdList);
|
||||
|
||||
/**
|
||||
* 通过用户名查询用户列表
|
||||
*
|
||||
* @param userName 用户名
|
||||
* @return 用户列表
|
||||
*/
|
||||
@GetMapping("/user/getUserListByUserName")
|
||||
R<List<SysUser>> getUserListByUserName(@RequestParam("username") String userName);
|
||||
/**
|
||||
* 通过用户名查询用户列表
|
||||
* @param userName 用户名
|
||||
* @return 用户列表
|
||||
*/
|
||||
@GetMapping("/user/getUserListByUserName")
|
||||
R<List<SysUser>> getUserListByUserName(@RequestParam("username") String userName);
|
||||
|
||||
/**
|
||||
* 注册用户
|
||||
*
|
||||
* @param userDTO 用户信息
|
||||
* @return success/false
|
||||
*/
|
||||
@PostMapping("/register/user")
|
||||
R<Boolean> registerUser(@RequestBody UserDTO userDTO, @RequestHeader(SecurityConstants.FROM) String from);
|
||||
/**
|
||||
* 注册用户
|
||||
* @param userDTO 用户信息
|
||||
* @return success/false
|
||||
*/
|
||||
@NoToken
|
||||
@PostMapping("/register/user")
|
||||
R<Boolean> registerUser(@RequestBody UserDTO userDTO);
|
||||
|
||||
}
|
||||
+2
-3
@@ -18,7 +18,6 @@
|
||||
package com.pig4cloud.pigx.admin.controller;
|
||||
|
||||
import com.pig4cloud.pigx.admin.api.feign.RemoteTokenService;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.log.annotation.SysLog;
|
||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||
@@ -53,7 +52,7 @@ public class SysTokenController {
|
||||
*/
|
||||
@RequestMapping("/page")
|
||||
public R getTokenPage(@RequestBody Map<String, Object> params) {
|
||||
return remoteTokenService.getTokenPage(params, SecurityConstants.FROM_IN);
|
||||
return remoteTokenService.getTokenPage(params);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,7 +65,7 @@ public class SysTokenController {
|
||||
@PreAuthorize("@pms.hasPermission('sys_token_del')")
|
||||
public R removeById(@RequestBody String[] tokens) {
|
||||
for (String token : tokens) {
|
||||
remoteTokenService.removeTokenById(token, SecurityConstants.FROM_IN);
|
||||
remoteTokenService.removeTokenById(token);
|
||||
}
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
+2
-3
@@ -4,7 +4,6 @@ import cn.hutool.core.util.CharUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.pig4cloud.pigx.admin.api.feign.RemoteTokenService;
|
||||
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.core.util.RetOps;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -32,7 +31,7 @@ public class JimuReportTokenService implements JmReportTokenServiceI {
|
||||
String tenant = StrUtil.subBefore(token, CharUtil.UNDERLINE, false);
|
||||
String tokenStr = StrUtil.subAfter(token, CharUtil.UNDERLINE, false);
|
||||
// @formatter:off
|
||||
return RetOps.of(tokenService.queryToken(tokenStr, tenant ,SecurityConstants.FROM_IN))
|
||||
return RetOps.of(tokenService.queryToken(tokenStr, tenant ))
|
||||
.getDataIf(RetOps.CODE_SUCCESS)
|
||||
.map(o -> (String)o.get("principalName"))
|
||||
.orElse(null);
|
||||
@@ -57,7 +56,7 @@ public class JimuReportTokenService implements JmReportTokenServiceI {
|
||||
// 分割出 PIGX 的租户信息
|
||||
String tenant = StrUtil.subBefore(token, CharUtil.UNDERLINE, false);
|
||||
String tokenStr = StrUtil.subAfter(token, CharUtil.UNDERLINE, false);
|
||||
R<Map<String, Object>> result = tokenService.queryToken(tokenStr,tenant , SecurityConstants.FROM_IN);
|
||||
R<Map<String, Object>> result = tokenService.queryToken(tokenStr,tenant );
|
||||
if (CommonConstants.SUCCESS.equals(result.getCode())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+2
-3
@@ -3,7 +3,6 @@ package com.pig4cloud.pigx.mp.config;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.pig4cloud.pigx.admin.api.feign.RemoteTenantService;
|
||||
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.core.util.RetOps;
|
||||
import com.pig4cloud.pigx.common.data.tenant.TenantBroker;
|
||||
import com.pig4cloud.pigx.mp.entity.WxAccount;
|
||||
@@ -97,7 +96,7 @@ public class WxMpInitConfigRunner {
|
||||
// 获取全部租户 遍历所有租户对应的公众号列表
|
||||
List<WxAccount> accountList = new ArrayList<>();
|
||||
// @formatter:off
|
||||
RetOps.of(tenantService.list(SecurityConstants.FROM_IN))
|
||||
RetOps.of(tenantService.list())
|
||||
.getData()
|
||||
.orElseGet(Collections::emptyList)
|
||||
.forEach(
|
||||
@@ -123,7 +122,7 @@ public class WxMpInitConfigRunner {
|
||||
private WxMpMessageRouter newRouter(WxMpService wxMpService) {
|
||||
final WxMpMessageRouter newRouter = new WxMpMessageRouter(wxMpService);
|
||||
|
||||
// 记录所有事件的日志 (异步执行)
|
||||
// 记录所有事件的日志 (异步执行) #5637 大数据量瓶颈
|
||||
newRouter.rule().handler(this.logHandler).next();
|
||||
|
||||
// 接收客服会话管理事件
|
||||
|
||||
+3
-2
@@ -79,8 +79,9 @@ public class SecurityRequestFilter extends OncePerRequestFilter {
|
||||
|
||||
// 获取用户信息
|
||||
Optional<String> principalName = RetOps
|
||||
.of(remoteTokenService.queryToken(accessToken, tenantId, SecurityConstants.FROM_IN))
|
||||
.getDataIf(RetOps.CODE_SUCCESS).map(o -> (String) o.get("principalName"));
|
||||
.of(remoteTokenService.queryToken(accessToken, tenantId))
|
||||
.getDataIf(RetOps.CODE_SUCCESS)
|
||||
.map(o -> (String) o.get("principalName"));
|
||||
|
||||
// 如果用户信息不存在,返回错误信息
|
||||
if (!principalName.isPresent()) {
|
||||
|
||||
Reference in new issue
Block a user