增加参数方法注入

要配合拦截器一起使用
先把需要的参数放到HttpServletRequest中的head中,然后在NativeWebRequest取出参数

先把参数放进HttpServletRequest中的head中request.setAttribute(REQUEST_CURRENT_USER, tokenUser);

package com.bsj.obd.authorization.interceptor;


import com.alibaba.fastjson.JSON;
import com.bsj.obd.authorization.annotation.Authorization;
import com.bsj.obd.authorization.annotation.Clear;
import com.bsj.obd.cached.RedisCached;
import com.bsj.obd.def.dto.TokenUser;
import com.bsj.obd.global.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;

/**
 * 自定义拦截器,对请求进行身份验证
 *
 * @date 2018/9/10 11:53
 */
@Component
@Slf4j
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
    public static final String REQUEST_CURRENT_USER = "REQUEST_CURRENT_USER";

    @Autowired
    private RedisCached redisCached;

    /**
     * @desc 拦截请求,处理
     **/
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        // 如果不是映射到方法直接通过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();

        // 判断请求的Controller类或方法是否有注解
        boolean authorizationMethod = method.getAnnotation(Authorization.class) != null;
//        String s=method.getName();
//        log.info("当前调用的方法名"+s);
        boolean clearMethod = method.getAnnotation(Clear.class) != null;
        //判断类上有没有这个注解
        boolean authorizationClazz = handlerMethod.getBeanType().getAnnotation(
                Authorization.class) != null;

        if (!(authorizationMethod || authorizationClazz) || clearMethod) {
            // 为了防止以恶意操作直接在REQUEST_CURRENT_KEY写入key,将其设为null
            request.setAttribute(REQUEST_CURRENT_USER, null);
            return true;
        }

        String sessionId = request.getHeader("sessionId");
        //验证token的值
        if (StringUtils.isNotBlank(sessionId)) {
            TokenUser tokenUser = redisCached.getUserInfo(sessionId);
            if (tokenUser != null) {
                request.setAttribute(REQUEST_CURRENT_USER, tokenUser);
//                log.info("-------------->用户缓存信息:{}", UserCached.getAllUserId(tokenUser.getUserId()));
                return true;
            }
        }

        //返回授权错误码给前端
        response.setStatus(401);
        returnMessage(request, response, 1);
        return false;
    }


    /**
     * * @desc 返回token失效信息
     *
     * @param request
     * @param response
     * @throws IOException
     */
    private void returnMessage(HttpServletRequest request, HttpServletResponse response, int type) throws IOException {
        // 跨域配置
        if (request.getHeader(HttpHeaders.ORIGIN) != null) {
            response.addHeader("Access-Control-Allow-Origin", "*");
            response.addHeader("Access-Control-Allow-Credentials", "true");
            response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT, HEAD");
            response.addHeader("Access-Control-Allow-Headers", "Content-Type");
            response.addHeader("Access-Control-Max-Age", "3600");
        }
        //这句话的意思,是让浏览器用utf8来解析返回的数据
        response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        //这句话的意思,是告诉servlet用UTF-8转码,而不是用默认的ISO8859
        response.setCharacterEncoding("UTF-8");
        PrintWriter out = response.getWriter();
        if (type == 0) {
            out.print(JSON.toJSONString(JsonResult.notAdminAuth()));
        } else if (type == 1) {
            out.print(JSON.toJSONString(JsonResult.notAuth()));
        }
        out.flush();
    }

}

增加方法注入

在所有的TokenUser参数或CurrentUser注解的将自动注入参数

package com.bsj.obd.authorization.resolvers;

import com.bsj.obd.authorization.annotation.CurrentUser;
import com.bsj.obd.authorization.interceptor.AuthorizationInterceptor;
import com.bsj.obd.def.dto.TokenUser;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;


/**
 * 增加方法注入,将含有CurrentUser注解的方法参数注入当前登录用户
 */
public class CurrentUserMethodArgumentResolver<T> implements HandlerMethodArgumentResolver {

    /**
     * 判定是否有TokenUser参数或CurrentUser注解,返回true调用下面的方法resolveArgument。
     *
     * @param parameter
     * @return
     */
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().isAssignableFrom(TokenUser.class)
                || parameter.hasParameterAnnotation(CurrentUser.class);
    }

    /**
     * 真正用于处理参数分解的方法,将在AuthorizationInterceptor中的参数强转返回
     *
     * @param parameter
     * @param mavContainer
     * @param webRequest
     * @param binderFactory
     * @return
     * @throws Exception
     */
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        TokenUser userModel = (TokenUser) webRequest.getAttribute(AuthorizationInterceptor.REQUEST_CURRENT_USER,
                RequestAttributes.SCOPE_REQUEST);
        if (userModel != null) {
            return userModel;
        }
        return null;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值