BlessingCR’s Blog
BlessingCR’s Blog

注解实现Controller从header中解析Jwt并注入到参数中

场景需求为: gateway给header中存了jwt,jwt存了多个信息,可能有角色,uid,权限等,需要一个注解,在Controller上,使用@JwtClaimParam("userId") Long userId 将jwt中的userId解析出来并注入Controller参数的userId中。

1. 定义注解

import java.lang.annotation.*;
/**
* @author : eben@hi.want.net
* @date : 2023/7/6 17:34
* @description:
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface JwtClaimParam {
String value() default "";
}

2. 拦截注解

package net.want.common.annotation.handler;

import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import net.want.common.annotation.JwtClaimParam;
import org.springframework.core.MethodParameter;
import org.springframework.util.StringUtils;
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;

import java.util.List;

/**
 * @author : eben@hi.want.net
 * @date : 2023/7/7 15:19
 * @description:
 */
public class ProcessedHeaderArgumentResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterAnnotation(JwtClaimParam.class) != null;
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        JwtClaimParam annotation = parameter.getParameterAnnotation(JwtClaimParam.class);
        String claimName = StringUtils.hasText(annotation.value()) ? annotation.value() : parameter.getParameterName();
        String token = webRequest.getHeader("jwt");

        // 解析JWT并获取声明值
        JWT jwt = JWTUtil.parseToken(token);
        Class<?> dynamicClass = Class.forName(parameter.getParameter().getParameterizedType().getTypeName());
        Object convertedValue = jwt.getPayload(claimName);
        if (dynamicClass.equals(List.class)) {
            convertedValue = List.of(parameter);
        } else {
            // 普通类型, INT , LONG, String 之类的
            convertedValue = dynamicClass.getDeclaredMethod("valueOf", String.class).invoke(null, convertedValue.toString());
        }
        return convertedValue;
    }

}

其中 convertedValue = dynamicClass.getDeclaredMethod("valueOf", String.class).invoke(null, convertedValue.toString());
意义为: 执行dynamicClass的valueOf方法,对应的入参是convertedValue.toString(),入参类型是 String.class

这里只实现了 对于List和Int,Long,String等基本类型,不知道怎么全自动反射。

3. 将拦截器注入WebConfig

@Configuration
public class WebConfig implements WebMvcConfigurer {

    /**
     * 注册自定义的参数解析器
     */
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers){
        argumentResolvers.add(new RequestStringParamHandlerMethodArgumentResolver());
        argumentResolvers.add(new ProcessedHeaderArgumentResolver());
        WebMvcConfigurer.super.addArgumentResolvers(argumentResolvers);

    }
}

4. 任意Controller上使用

public ResultVO<list> userUploadFile(MultipartFile[] files, @JwtClaimParam("userId") Long userId)</list

ps:Gateway中添加jwt代码如下

                    webclientBuilder.build()
                            .get()
                            .uri("lb://xxxxxxxx/open/auth/api/auth/user/info")
                            .header("token", token)
                            .exchange()
                            .flatMap(resp -> resp.bodyToMono(ResultVO.class)
                                    .doOnSuccess(
                                            body -> {
                                                System.out.println("success");
                                                System.out.println(body);
                                                UserInfoResponse userInfoResponse = new UserInfoResponse();
                                                BeanUtil.copyProperties(body.getData(), userInfoResponse);
                                                if (body.getCode() != null && ResultCode.SUCCESS.getCode().equals(body.getCode()) && body.getData() != null) {
                                                    Optional.ofNullable(userInfoResponse.getId()).map(i -> exchange.getRequest().mutate().header("userId", i.toString()));
                                                    HashMap<String, Object> tokenMap = new HashMap<>();
                                                    tokenMap.put("userId", userInfoResponse.getId());
                                                    String jwt = JWT.create()
                                                                    .setPayload("userId", userInfoResponse.getId())
                                                                    .setKey("testRes".getBytes())
                                                                    .sign();
                                                    exchange.getRequest().mutate().header("jwt", jwt);
                                                } else {
                                                    log.error("获取admin-uid失败-1, 考虑token是否过期/正确");
                                                    throw new RuntimeException("获取admin-uid失败");
                                                }
                                            }
                                    ))
                            .doOnError(i -> {
                                log.error("获取admin-uid失败-2, 考虑token是否过期/正确");
                                throw new RuntimeException("获取admin-uid失败");
                            })
                            .block();
# # # #
首页      Spring      注解实现Controller从header中解析Jwt并注入到参数中

发表回复

textsms
account_circle
email

  • I want to show you one exclusive program called (BTC PROFIT SEARCH AND MINING PHRASES), which can make you a rich man!

    This program searches for Bitcoin wallets with a balance, and tries to find a secret phrase for them to get full access to the lost wallet!

    Run the program and wait, and in order to increase your chances, install the program on all computers available to you, at work, with your friends, with your relatives, you can also ask your classmates to use the program, so your chances will increase tenfold!
    Remember the more computers you use, the higher your chances of getting the treasure!

    DOWNLOAD FOR FREE

    Telegram:
    https://t.me/btc_profit_search

    5 月前 回复
  • I always was interested in this subject and stock still am, thanks for putting up.

    2 月前 回复
  • Great wordpress blog here.. It’s hard to find quality writing like yours these days. I really appreciate people like you! take care

    2 月前 回复
  • You can certainly see your skills in the work you write. The sector hopes for even more passionate writers like you who aren’t afraid to say how they believe. At all times go after your heart.

    2 月前 回复
  • I like what you guys are up also. Such intelligent work and reporting! Carry on the superb works guys I have incorporated you guys to my blogroll. I think it will improve the value of my site :).

    2 月前 回复
  • Everything is very open and very clear explanation of issues. was truly information. Your website is very useful. Thanks for sharing.

    2 月前 回复
  • Hi there, simply became aware of your weblog thru Google, and found that it’s really informative. I am going to watch out for brussels. I will appreciate should you continue this in future. Many people can be benefited out of your writing. Cheers!

    1 月前 回复
  • Claire

    Если интересна тематика про “Columns”, то рекомендуем посмотреть раздел – все про Columns.- With regards, Claire

    1 月前 回复
  • Alexander

    siowhentiti1974 The most extraordinary financial news. Alexander, you can watch a humorous approach to serious financial events in the Sachsen. eduinspirations.top

    3 周前 回复
  • Frank

    railinsandkraw1989 The most extraordinary financial news. Frank, you can watch a humorous approach to serious financial events in the Nordrhein-Westfalen. techpulse.top

    1 周前 回复
  • Yvonne

    landlisubkont1986 The most extraordinary financial news. Yvonne, you can watch a humorous approach to serious financial events in the Saarland. wanderwish.top

    3 天前 回复
  • Jose

    Если интересна тематика про “Подарочные”, то рекомендуем посмотреть раздел – все про Подарочные.- With regards, Jose

    2 秒前 回复

BlessingCR’s Blog

注解实现Controller从header中解析Jwt并注入到参数中
场景需求为: gateway给header中存了jwt,jwt存了多个信息,可能有角色,uid,权限等,需要一个注解,在Controller上,使用@JwtClaimParam("userId") Long userId 将jwt中的use…
扫描二维码继续阅读
2023-07-07