15 changed files with 601 additions and 6 deletions
@ -0,0 +1,35 @@ |
|||||
|
/** |
||||
|
* Copyright 2018 人人开源 http://www.renren.io
|
||||
|
* <p> |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not |
||||
|
* use this file except in compliance with the License. You may obtain a copy of |
||||
|
* the License at |
||||
|
* <p> |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* <p> |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
||||
|
* License for the specific language governing permissions and limitations under |
||||
|
* the License. |
||||
|
*/ |
||||
|
|
||||
|
package com.epmet.commons.tools.annotation; |
||||
|
|
||||
|
import java.lang.annotation.ElementType; |
||||
|
import java.lang.annotation.Retention; |
||||
|
import java.lang.annotation.RetentionPolicy; |
||||
|
import java.lang.annotation.Target; |
||||
|
|
||||
|
/** |
||||
|
* 登录用户信息 |
||||
|
* |
||||
|
* @author chenshun |
||||
|
* @email sunlightcs@gmail.com |
||||
|
* @date 2017-03-23 20:39 |
||||
|
*/ |
||||
|
@Target(ElementType.PARAMETER) |
||||
|
@Retention(RetentionPolicy.RUNTIME) |
||||
|
public @interface LoginUser { |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,49 @@ |
|||||
|
/** |
||||
|
* Copyright (c) 2018 人人开源 All rights reserved. |
||||
|
* |
||||
|
* https://www.renren.io
|
||||
|
* |
||||
|
* 版权所有,侵权必究! |
||||
|
*/ |
||||
|
|
||||
|
package com.epmet.config; |
||||
|
|
||||
|
import com.epmet.resolver.LoginUserHandlerMethodArgumentResolver; |
||||
|
import com.fasterxml.jackson.databind.DeserializationFeature; |
||||
|
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
|
import com.fasterxml.jackson.databind.module.SimpleModule; |
||||
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; |
||||
|
import com.epmet.commons.tools.security.resolver.UserDetailHandlerMethodArgumentResolver; |
||||
|
import com.epmet.commons.tools.utils.DateUtils; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.context.annotation.Bean; |
||||
|
import org.springframework.context.annotation.Configuration; |
||||
|
import org.springframework.http.converter.ByteArrayHttpMessageConverter; |
||||
|
import org.springframework.http.converter.HttpMessageConverter; |
||||
|
import org.springframework.http.converter.ResourceHttpMessageConverter; |
||||
|
import org.springframework.http.converter.StringHttpMessageConverter; |
||||
|
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; |
||||
|
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter; |
||||
|
import org.springframework.web.method.support.HandlerMethodArgumentResolver; |
||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
||||
|
|
||||
|
import java.text.SimpleDateFormat; |
||||
|
import java.util.List; |
||||
|
import java.util.TimeZone; |
||||
|
|
||||
|
/** |
||||
|
* MVC配置 |
||||
|
* |
||||
|
* @author Mark sunlightcs@gmail.com |
||||
|
* @since 1.0.0 |
||||
|
*/ |
||||
|
@Configuration |
||||
|
public class WebConfig implements WebMvcConfigurer { |
||||
|
// @Autowired
|
||||
|
// private LoginUserHandlerMethodArgumentResolver loginUserHandlerMethodArgumentResolver;
|
||||
|
|
||||
|
@Override |
||||
|
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { |
||||
|
argumentResolvers.add(new LoginUserHandlerMethodArgumentResolver()); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
/** |
||||
|
* Copyright (c) 2018 人人开源 All rights reserved. |
||||
|
* |
||||
|
* https://www.renren.io
|
||||
|
* |
||||
|
* 版权所有,侵权必究! |
||||
|
*/ |
||||
|
|
||||
|
package com.epmet.exception; |
||||
|
|
||||
|
|
||||
|
import com.epmet.commons.tools.exception.ErrorCode; |
||||
|
|
||||
|
/** |
||||
|
* 模块错误编码,由9位数字组成,前6位为模块编码,后3位为业务编码 |
||||
|
* <p> |
||||
|
* 如:100001001(100001代表模块,001代表业务代码) |
||||
|
* </p> |
||||
|
* |
||||
|
* @author Mark sunlightcs@gmail.com |
||||
|
* @since 1.0.0 |
||||
|
*/ |
||||
|
public interface ModuleErrorCode extends ErrorCode { |
||||
|
int TOKEN_NOT_EMPTY = 100005001; |
||||
|
int TOKEN_INVALID = 100005002; |
||||
|
} |
||||
@ -0,0 +1,159 @@ |
|||||
|
|
||||
|
package com.epmet.filter; |
||||
|
|
||||
|
import com.alibaba.fastjson.JSON; |
||||
|
import com.epmet.common.token.dto.TokenDto; |
||||
|
import com.epmet.common.token.util.CpUserDetailRedis; |
||||
|
import com.epmet.commons.tools.constant.Constant; |
||||
|
import com.epmet.commons.tools.exception.ErrorCode; |
||||
|
import com.epmet.commons.tools.exception.RenException; |
||||
|
import com.epmet.commons.tools.utils.Result; |
||||
|
import com.epmet.jwt.JwtTokenUtils; |
||||
|
import io.jsonwebtoken.Claims; |
||||
|
import org.apache.commons.lang3.StringUtils; |
||||
|
import org.slf4j.Logger; |
||||
|
import org.slf4j.LoggerFactory; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.cloud.gateway.filter.GatewayFilter; |
||||
|
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; |
||||
|
import org.springframework.core.io.buffer.DataBuffer; |
||||
|
import org.springframework.http.HttpHeaders; |
||||
|
import org.springframework.http.HttpStatus; |
||||
|
import org.springframework.http.MediaType; |
||||
|
import org.springframework.http.server.reactive.ServerHttpRequest; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
import org.springframework.util.AntPathMatcher; |
||||
|
import org.springframework.web.server.ServerWebExchange; |
||||
|
import reactor.core.publisher.Flux; |
||||
|
import reactor.core.publisher.Mono; |
||||
|
|
||||
|
import java.nio.charset.StandardCharsets; |
||||
|
import java.util.Arrays; |
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* app接口权限过滤器 |
||||
|
* |
||||
|
* @author Mark sunlightcs@gmail.com |
||||
|
* @since 1.0.0 |
||||
|
*/ |
||||
|
@Component("CpAuth") |
||||
|
public class CpAuthGatewayFilterFactory extends AbstractGatewayFilterFactory<CpAuthGatewayFilterFactory.CpAuthConfig> { |
||||
|
private Logger logger = LoggerFactory.getLogger(getClass()); |
||||
|
@Autowired |
||||
|
private CpProperty cpProperty; |
||||
|
private final AntPathMatcher antPathMatcher = new AntPathMatcher(); |
||||
|
@Autowired |
||||
|
private JwtTokenUtils jwtTokenUtils; |
||||
|
@Autowired |
||||
|
private CpUserDetailRedis cpUserDetailRedis; |
||||
|
|
||||
|
|
||||
|
@Override |
||||
|
public List<String> shortcutFieldOrder() { |
||||
|
return Arrays.asList("enabled"); |
||||
|
} |
||||
|
|
||||
|
public CpAuthGatewayFilterFactory() { |
||||
|
super(CpAuthConfig.class); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public GatewayFilter apply(CpAuthConfig config) { |
||||
|
return (exchange, chain) -> { |
||||
|
if (!config.isEnabled()) { |
||||
|
logger.info("==========="); |
||||
|
return chain.filter(exchange); |
||||
|
} |
||||
|
|
||||
|
ServerHttpRequest request = exchange.getRequest(); |
||||
|
String requestUri = request.getPath().pathWithinApplication().value(); |
||||
|
|
||||
|
//请求放行,无需验证权限
|
||||
|
if (!pathMatcher(requestUri)) { |
||||
|
return chain.filter(exchange); |
||||
|
} |
||||
|
logger.info("CpAuthGatewayFilterFactory当前requestUri=[" + requestUri + "]CpAuthGatewayFilterFactory拦截成功"); |
||||
|
HttpHeaders headers = request.getHeaders(); |
||||
|
String token = headers.getFirst(Constant.AUTHORIZATION_HEADER); |
||||
|
// String token = request.getQueryParams().getFirst(Constant.TOKEN_HEADER);
|
||||
|
if (StringUtils.isBlank(token)) { |
||||
|
token = request.getQueryParams().getFirst(Constant.AUTHORIZATION_HEADER); |
||||
|
if (StringUtils.isBlank(token)) { |
||||
|
return chain.filter(exchange); |
||||
|
} |
||||
|
} |
||||
|
TokenDto user = this.getLoginUserInfo(token); |
||||
|
//当前登录用户userId,添加到header中
|
||||
|
if (user != null) { |
||||
|
String redisKey = user.getApp() + "-" + user.getClient() + "-" + user.getUserId(); |
||||
|
logger.info("redisKey=" + redisKey); |
||||
|
ServerHttpRequest build = exchange.getRequest().mutate().header(Constant.APP_USER_KEY, redisKey).build(); |
||||
|
return chain.filter(exchange.mutate().request(build).build()); |
||||
|
} |
||||
|
return chain.filter(exchange); |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
public TokenDto getLoginUserInfo(String token) { |
||||
|
//是否过期
|
||||
|
Claims claims = jwtTokenUtils.getClaimByToken(token); |
||||
|
if (claims == null || jwtTokenUtils.isTokenExpired(claims.getExpiration())) { |
||||
|
throw new RenException(ErrorCode.UNAUTHORIZED); |
||||
|
} |
||||
|
//获取用户ID
|
||||
|
String app = (String) claims.get("app"); |
||||
|
String client = (String) claims.get("client"); |
||||
|
String userId = (String) claims.get("userId"); |
||||
|
//查询Redis,如果没数据,则保持用户信息到Redis
|
||||
|
TokenDto tokenDto = cpUserDetailRedis.get(app, client, userId); |
||||
|
if (null == tokenDto) { |
||||
|
throw new RenException(ErrorCode.REGION_SUB_DELETE_ERROR, Constant.TOKEN_HEADER); |
||||
|
} |
||||
|
//过期时间
|
||||
|
long expire = (claims.getExpiration().getTime() - System.currentTimeMillis()) / 1000; |
||||
|
cpUserDetailRedis.set(tokenDto, expire); |
||||
|
return tokenDto; |
||||
|
} |
||||
|
|
||||
|
private Mono<Void> response(ServerWebExchange exchange, Object object) { |
||||
|
String json = JSON.toJSONString(object); |
||||
|
DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(json.getBytes(StandardCharsets.UTF_8)); |
||||
|
exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON_UTF8); |
||||
|
exchange.getResponse().setStatusCode(HttpStatus.OK); |
||||
|
return exchange.getResponse().writeWith(Flux.just(buffer)); |
||||
|
} |
||||
|
|
||||
|
private boolean pathMatcher(String requestUri) { |
||||
|
for (String url : cpProperty.getSwaggerUrls()) { |
||||
|
if (antPathMatcher.match(url, requestUri)) { |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
for (String url : cpProperty.getUrls()) { |
||||
|
if (antPathMatcher.match(url, requestUri)) { |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
public static class CpAuthConfig { |
||||
|
|
||||
|
/** |
||||
|
* 控制是否开启认证 |
||||
|
*/ |
||||
|
private boolean enabled; |
||||
|
|
||||
|
public CpAuthConfig() { |
||||
|
} |
||||
|
|
||||
|
public boolean isEnabled() { |
||||
|
return enabled; |
||||
|
} |
||||
|
|
||||
|
public void setEnabled(boolean enabled) { |
||||
|
this.enabled = enabled; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
package com.epmet.filter; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* @author rongchao |
||||
|
* @Date 19-5-17 |
||||
|
*/ |
||||
|
@Data |
||||
|
@Component |
||||
|
@EnableConfigurationProperties |
||||
|
@ConfigurationProperties(prefix = "epmet") |
||||
|
public class CpProperty { |
||||
|
|
||||
|
private List<String> urls; |
||||
|
|
||||
|
/** |
||||
|
* 不处理token,直接通过 |
||||
|
*/ |
||||
|
private List<String> swaggerUrls; |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,41 @@ |
|||||
|
/** |
||||
|
* Copyright (c) 2018 人人开源 All rights reserved. |
||||
|
* |
||||
|
* https://www.renren.io
|
||||
|
* |
||||
|
* 版权所有,侵权必究! |
||||
|
*/ |
||||
|
|
||||
|
package com.epmet.jwt; |
||||
|
|
||||
|
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
|
import org.springframework.context.annotation.Configuration; |
||||
|
|
||||
|
/** |
||||
|
* Jwt |
||||
|
* |
||||
|
* @author Mark sunlightcs@gmail.com |
||||
|
* @since 1.0.0 |
||||
|
*/ |
||||
|
@Configuration |
||||
|
@ConfigurationProperties(prefix = "jwt.token") |
||||
|
public class JwtTokenProperties { |
||||
|
private String secret; |
||||
|
private int expire; |
||||
|
|
||||
|
public String getSecret() { |
||||
|
return secret; |
||||
|
} |
||||
|
|
||||
|
public void setSecret(String secret) { |
||||
|
this.secret = secret; |
||||
|
} |
||||
|
|
||||
|
public int getExpire() { |
||||
|
return expire; |
||||
|
} |
||||
|
|
||||
|
public void setExpire(int expire) { |
||||
|
this.expire = expire; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,132 @@ |
|||||
|
/** |
||||
|
* Copyright (c) 2018 人人开源 All rights reserved. |
||||
|
* <p> |
||||
|
* https://www.renren.io
|
||||
|
* <p> |
||||
|
* 版权所有,侵权必究! |
||||
|
*/ |
||||
|
|
||||
|
package com.epmet.jwt; |
||||
|
|
||||
|
import io.jsonwebtoken.Claims; |
||||
|
import io.jsonwebtoken.Jwts; |
||||
|
import io.jsonwebtoken.SignatureAlgorithm; |
||||
|
import org.apache.commons.codec.binary.Base64; |
||||
|
import org.joda.time.DateTime; |
||||
|
import org.slf4j.Logger; |
||||
|
import org.slf4j.LoggerFactory; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
import java.util.Calendar; |
||||
|
import java.util.Date; |
||||
|
import java.util.HashMap; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
/** |
||||
|
* Jwt工具类 |
||||
|
* |
||||
|
* @author Mark sunlightcs@gmail.com |
||||
|
* @since 1.0.0 |
||||
|
*/ |
||||
|
@Component |
||||
|
public class JwtTokenUtils { |
||||
|
private static final Logger logger = LoggerFactory.getLogger(JwtTokenUtils.class); |
||||
|
|
||||
|
@Autowired |
||||
|
private JwtTokenProperties jwtProperties; |
||||
|
|
||||
|
/** |
||||
|
* 生成jwt token 弃用 |
||||
|
*/ |
||||
|
@Deprecated |
||||
|
public String generateToken(String userId) { |
||||
|
return Jwts.builder() |
||||
|
.setHeaderParam("typ", "JWT") |
||||
|
.setSubject(userId) |
||||
|
.setIssuedAt(new Date()) |
||||
|
.setExpiration(DateTime.now().plusSeconds(jwtProperties.getExpire()).toDate()) |
||||
|
.signWith(SignatureAlgorithm.HS512, jwtProperties.getSecret()) |
||||
|
.compact(); |
||||
|
} |
||||
|
|
||||
|
public Claims getClaimByToken(String token) { |
||||
|
try { |
||||
|
return Jwts.parser() |
||||
|
.setSigningKey(jwtProperties.getSecret()) |
||||
|
.parseClaimsJws(token) |
||||
|
.getBody(); |
||||
|
} catch (Exception e) { |
||||
|
logger.debug("validate is token error, token = " + token, e); |
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return java.util.Date |
||||
|
* @param token |
||||
|
* @Author yinzuomei |
||||
|
* @Description 获取token的有效期截止时间 |
||||
|
* @Date 2020/3/18 22:17 |
||||
|
**/ |
||||
|
public Date getExpiration(String token){ |
||||
|
try { |
||||
|
return Jwts.parser() |
||||
|
.setSigningKey(jwtProperties.getSecret()) |
||||
|
.parseClaimsJws(token) |
||||
|
.getBody().getExpiration(); |
||||
|
} catch (Exception e) { |
||||
|
logger.debug("validate is token error, token = " + token, e); |
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param map |
||||
|
* @return java.lang.String |
||||
|
* @Author yinzuomei |
||||
|
* @Description 根据app+client+userId生成token |
||||
|
* @Date 2020/3/18 22:29 |
||||
|
**/ |
||||
|
public String createToken(Map<String, Object> map) { |
||||
|
return Jwts.builder() |
||||
|
.setHeaderParam("typ", "JWT") |
||||
|
.setClaims(map) |
||||
|
.setIssuedAt(new Date()) |
||||
|
.setExpiration(DateTime.now().plusSeconds(jwtProperties.getExpire()).toDate()) |
||||
|
.signWith(SignatureAlgorithm.HS512, jwtProperties.getSecret()) |
||||
|
.compact(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* token是否过期 |
||||
|
* |
||||
|
* @return true:过期 |
||||
|
*/ |
||||
|
public boolean isTokenExpired(Date expiration) { |
||||
|
return expiration.before(new Date()); |
||||
|
} |
||||
|
|
||||
|
public static void main(String[] args) { |
||||
|
Map<String, Object> map=new HashMap<>(); |
||||
|
map.put("app","gov"); |
||||
|
map.put("client","wxmp"); |
||||
|
map.put("userId","100526ABC"); |
||||
|
String tokenStr=Jwts.builder() |
||||
|
.setHeaderParam("typ", "JWT") |
||||
|
.setClaims(map) |
||||
|
.setIssuedAt(new Date()) |
||||
|
.setExpiration(DateTime.now().plusSeconds(604800).toDate()) |
||||
|
.signWith(SignatureAlgorithm.HS512, "7016867071f0ebf1c46f123eaaf4b9d6[elink.epmet]") |
||||
|
.compact(); |
||||
|
System.out.println(tokenStr); |
||||
|
Claims claims= Jwts.parser() |
||||
|
.setSigningKey("7016867071f0ebf1c46f123eaaf4b9d6[elink.epmet]") |
||||
|
.parseClaimsJws(tokenStr) |
||||
|
.getBody(); |
||||
|
System.out.println("app="+ claims.get("app")); |
||||
|
System.out.println("client="+ claims.get("client")); |
||||
|
System.out.println("userId="+ claims.get("userId")); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,66 @@ |
|||||
|
/** |
||||
|
* Copyright (c) 2018 人人开源 All rights reserved. |
||||
|
* <p> |
||||
|
* https://www.renren.io
|
||||
|
* <p> |
||||
|
* 版权所有,侵权必究! |
||||
|
*/ |
||||
|
|
||||
|
package com.epmet.resolver; |
||||
|
|
||||
|
import com.alibaba.fastjson.JSON; |
||||
|
import com.epmet.common.token.dto.TokenDto; |
||||
|
import com.epmet.common.token.util.CpUserDetailRedis; |
||||
|
import com.epmet.commons.tools.annotation.LoginUser; |
||||
|
import com.epmet.commons.tools.constant.Constant; |
||||
|
import com.epmet.commons.tools.exception.RenException; |
||||
|
import com.epmet.exception.ModuleErrorCode; |
||||
|
import org.apache.commons.lang3.StringUtils; |
||||
|
import org.slf4j.Logger; |
||||
|
import org.slf4j.LoggerFactory; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.core.MethodParameter; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
import org.springframework.web.bind.support.WebDataBinderFactory; |
||||
|
import org.springframework.web.context.request.NativeWebRequest; |
||||
|
import org.springframework.web.method.support.HandlerMethodArgumentResolver; |
||||
|
import org.springframework.web.method.support.ModelAndViewContainer; |
||||
|
|
||||
|
/** |
||||
|
* 有@LoginUser注解的方法参数,注入当前登录用户 |
||||
|
* |
||||
|
* @author Mark sunlightcs@gmail.com |
||||
|
*/ |
||||
|
//@Component
|
||||
|
public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver { |
||||
|
private Logger logger = LoggerFactory.getLogger(getClass()); |
||||
|
@Autowired |
||||
|
private CpUserDetailRedis cpUserDetailRedis; |
||||
|
|
||||
|
public LoginUserHandlerMethodArgumentResolver(){ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean supportsParameter(MethodParameter parameter) { |
||||
|
logger.info("enter supportsParameter "); |
||||
|
return parameter.getParameterType().isAssignableFrom(TokenDto.class) && parameter.hasParameterAnnotation(LoginUser.class); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container, |
||||
|
NativeWebRequest request, WebDataBinderFactory factory) throws Exception { |
||||
|
//app-client-userId
|
||||
|
String redisKey = request.getHeader(Constant.APP_USER_KEY); |
||||
|
if (StringUtils.isEmpty(redisKey)) { |
||||
|
throw new RenException(ModuleErrorCode.TOKEN_INVALID); |
||||
|
} |
||||
|
String[] keyArray=redisKey.split("-"); |
||||
|
String app=keyArray[0]; |
||||
|
String client=keyArray[1]; |
||||
|
String userId=keyArray[2]; |
||||
|
TokenDto tokenDto = cpUserDetailRedis.get(app,client,userId); |
||||
|
logger.info("resolveArgument TokenDto:"+ JSON.toJSONString(tokenDto)); |
||||
|
return tokenDto; |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue