springboot+resteasy过滤器 (登录态认证demo)

resteasy 3.x以前的版本是只有拦截器,3.x版本以后以前的拦截器被标记为过时了,新版适用过滤器代替
jboss官方说明地址(版本4.7.0.Final):https://docs.jboss.org/resteasy/docs/4.7.0.Final/userguide/html/Interceptors.html

官方新版说明不太详细,这里整理一下实测结果。
采用springboot + resteasy ,集成参考:https://github.com/paypal/resteasy-spring-boot

接口身份验证过滤器,适用 jwt 生成token

代码较糙,后续优化,请谅解哈

@Provider
@JaxrsCheckLogin
@Slf4j
public class JaxrsAuthorizationInterceptor implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {

        try {
            // 从cookie中获取token
            String token = "";
            Map<String, Cookie> cookies = requestContext.getCookies();
            if (CollectionUtils.isEmpty(cookies)) {
                throw new BusinessException("cookies is null");
            }
            //获取token
            for (Map.Entry<String, Cookie> entry : cookies.entrySet()) {
                if ("token".equals(entry.getKey())) {
                    token = entry.getValue()==null?null:entry.getValue().getValue();
                }
            }

            // 开始验证登录
            if (StringUtil.isBlank(token)) {
                throw new BusinessException(AuthResultCode.NOT_LOGIN);
            }

            try {
                // jwt 验证 token 是否正确
                JwtUtils.checkToken(token);
            } catch (JWTVerificationException e) {
                log.warn("jwt token check exception :", e);
                throw new BusinessException(AuthResultCode.TOKEN_IS_INVALID);
            }

            List<String> list = JWT.decode(token).getAudience();
            log.info("JWT decode token result : {}", JSONObject.toJSONString(list));
            LoginInfoVO loginInfoVO = JSONObject.parseObject(list.get(0), LoginInfoVO.class);

            // 需验证登录,token过期时间
            if (LoginInfoVO.getTokenExp().before(LocalDateTime.now().toDate())) {
                throw new BusinessException(AuthResultCode.TOKEN_EXPIRE);
            }
            requestContext.getHeaders().add("userInfo", JSON.toJSONString(loginInfoVO));

        } catch (BusinessException e) {
            log.error("Authorization businessException : ", e);
            requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).entity(e.getMessage()).build());
        } catch (Throwable e) {
            log.error("Authorization Throwable: ", e);
            requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).entity(e.getMessage()).build());
        }
    }
}

注意如果filter方法抛出异常,会重定向到/error页面。

@Provider注解是必须的。
ContainerRequestFilter 默认是匹配资源方法后触发的过滤器,如果想要匹配资源前触发增加@PreMatching。
相关源码如下

// execute pre match filters
        for (ContainerRequestFilter filter : preMatchFilters) {
            filter.filter(requestContext);
            if (isAborted(requestContext)) {
               sendAbortionToClient(requestContext);
               return;
            }
        }
        // match the HTTP request to a resource class and method
        JaxrsMethod method = matchMethod(requestContext);

        // Execute post match filters
        for (ContainerRequestFilter filter : postMatchFilters) {
           filter.filter(requestContext);
           if (isAborted(requestContext)) {
              sendAbortionToClient(requestContext);
              return;
           }
        }

        // execute resource class method
        method.execute(request);

        // execute response filters
        for (ContainerResponseFilter filter : responseFilters) {
           filter.filter(requestContext, responseContext);
        }

@BindingPriority(3):此注解是标志过滤器优先级,方法参数值越大优先级越高。此注解适用在方法上。

与springboot继承后,官方的写法并不会生效,结合与springboot集成说明,增加注册过滤器。

@Component
@ApplicationPath("/rs")
public class JaxrsApplication extends Application{
    @Override
    public Set<Object> getSingletons() {
        Set<Object> singletons = new HashSet<>();
        singletons.add(new MyInterceptor());
        return singletons;
    }
}

@JaxrsCheckLogin 是自定义注解,作用是,绑定此过滤器到添加此注解的资源方法上,可以指定在类上或方法上。写法如下

@NameBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface JaxrsCheckLogin {
}

LoginInfoVO 要实现一个静态方法valueOf(String header)
参数是从header中获取的字符串,返回当前类型的对象,就可以在资源方法里自动获取这个对象了

接口方法写法如下:

@Component
@Path("/wado")
@JaxrsCheckLogin
public class WadoRs {
    @GET
    @Path("/studies")
    public Response studies(@PathParam("studyUID") String studyUID,@HeaderParam("userInfo") LoginInfoVO userInfo) {
        Response res = null;
        return res;
    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值