♻️ 增加 NoToken 注解方便对应 无token feign调用场景

This commit is contained in:
冷冷 committed 2024-08-21 22:17:24 +08:00
1 parent a7552c6a5c
commit 13f13d4813
27 files changed
+440 -335

No files matched your search

@@ -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);
@@ -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);
}
}
}
@@ -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);
}
}
@@ -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);
+5
View File
@@ -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>
@@ -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();
}
}
@@ -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 {
}
@@ -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;
}
}
@@ -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");
}
}
@@ -88,7 +88,7 @@ public class SysLogListener implements InitializingBean {
}
source.setBody(null);
remoteLogService.saveLog(source, SecurityConstants.FROM_IN);
remoteLogService.saveLog(source);
}
@Override
@@ -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;
@@ -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);
}
@@ -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();
}
@@ -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);
}
@@ -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);
}
}
@@ -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);
}
@@ -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();
}
@@ -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);
}
@@ -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);
}
@@ -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();
}
@@ -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);
}
@@ -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);
}
@@ -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();
}
@@ -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;
}
@@ -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();
// 接收客服会话管理事件
@@ -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()) {