黑马十次方项目day08-07 后台Zuul网关权限验证

一. 引入依赖

修改tensquare_manager的过滤器, 因为是管理后台使用,所以需要在过滤器中对token
进行验证.
在tensquare_manager引入tensquare_common依赖 ,因为需要用到其中的JWT工
具类.

		<dependency>
            <groupId>com.tensquare</groupId>
            <artifactId>tensquare_common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

二.修改tensquare_manager配置文件application.yml

在yml中,加入jwt的盐值

jwt:
  config:
    key: itcast    # 设置token的盐为 itcast

三. 修改tensquare_manager的启动类,添加bean

在com.tensquare.manager.ManagerApplication

/**
     * 把jwt对象注入容器中
     * @return
     */
    @Bean
    public JwtUtil jwtUtil(){
        return new JwtUtil();
    }

四.tensquare_manager编写过滤器类

在com.tensquare.manager.filter.ManagerFilter 中,编写如下的过滤器.

在通过requestContext.setSendZuulResponse(false)令zuul过滤该请求,不对其
进行路由,然后通过 requestContext.setResponseStatusCode(401)设置了其返回的错误码

在run方法中,对token进行了校验. 并注意要放行网关分发的OPPTIONS方法和登录的请求.

package com.tensquare.manager.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import util.JwtUtil;

import javax.servlet.http.HttpServletRequest;

/**
 * 类名称:ManagerFilter
 * 类描述:  zuul 网关过滤器
 *
 * @author: taohongchao
 * 创建时间:2019/2/23 14:08
 * Version 1.0
 */
@Component
public class ManagerFilter extends ZuulFilter {

    @Autowired
    private JwtUtil jwtUtil;
	
	/**
     * 方法名: run
     * 方法描述:  过滤器内执行的操作, return代表任何Object的值(包括null),都代表继续执行
     * 而调用 setSendZuulResponse(false) 表示不再继续执行
     * 修改日期: 2019/2/23 14:13
      * @param          
     * @return java.lang.Object
     * @author taohongchao
     * @throws
     */
    @Override
    public Object run() throws ZuulException {


        //获取上下文
        RequestContext requestContext = RequestContext.getCurrentContext();

        //获取Resquest
        HttpServletRequest request = requestContext.getRequest();

        //获取认证的头信息
        String header = request.getHeader("Authorization");

        //放行网关的第一次请求的分发服务的请求.该请求的方法为OPTTIONS
        if(request.getMethod().equals("OPTIONS")){
            return null;
        }

        //放行登录的请求
        if(request.getRequestURI().indexOf("login")>0){
            return null;
        }

        if (StringUtils.isNotBlank(header)) {
            if (header.startsWith("Bearer ")) {
                String token = header.substring(7);

                try {
                    //解析token
                    Claims claims = jwtUtil.parseJWT(token);
                    //获取角色
                    String role = (String) claims.get("roles");
                    if ("admin".equals(role)) {
                        //只有是管理员角色的时候,才把请求放行
                        requestContext.addZuulRequestHeader("Authorization",header);
                        return null;
                    }
                } catch (Exception e) {
                    //解析token出现异常, 不放行此请求
                    e.printStackTrace();
                    //终止运行,不放行
                    requestContext.setSendZuulResponse(false);
                }
            }
        }
        //终止请求, 不再继续执行
        requestContext.setSendZuulResponse(false);
        //403代表权限不足
        requestContext.setResponseStatusCode(403);
        requestContext.setResponseBody("权限不足");
        requestContext.getResponse().setContentType("text/html;charset=utf-8");
        return null;
    }

    /**
     * 方法名: filterType
     * 方法描述:  过滤器执行的类型
     * pre 代表在执行之前执行, 一般使用pre 进行之前过滤
     * post 代表在当前操作之后过滤
     * 修改日期: 2019/2/23 14:10
      * @param
     * @return java.lang.String
     * @author taohongchao
     * @throws
     */
    @Override
    public String filterType() {
        return "pre";
    }

    /**
     * 方法名: filterOrder
     * 方法描述: 多个过滤器执行顺序, 数字越小,代表越前执行
     * 修改日期: 2019/2/23 14:12
      * @param
     * @return int
     * @author taohongchao
     * @throws
     */
    @Override
    public int filterOrder() {
        return 0;
    }

    
    /**
     * 方法名: shouldFilter
     * 方法描述: 当前过滤器是否开启, true代表开启, false代表关闭该过滤器
     * 修改日期: 2019/2/23 14:13
      * @param          
     * @return boolean
     * @author taohongchao
     * @throws
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }
}

五.对后台网关权限验证的测试

启动响应的工程. 发送如下的请求http://localhost:9011/base/label如果不带token,获取请求头的token信息错误,则会返回如下图的信息,提示权限不足
黑马十次方项目day08-07 后台Zuul网关权限验证
通过管理员账号登录,获取token
eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxMDg5ODU1MTIzNTc4MDMyMTI4Iiwic3ViIjoiYWRtaW4iLCJpYXQiOjE1NTA5MDg4OTEsInJvbGVzIjoiYWRtaW4iLCJleHAiOjE1NTA5MTI0OTF9.f-EYjQ8nxI2ED1iON01Sx611rZm4pyjNIMkQ3rxSLw0
在请求信息中,带上此token
黑马十次方项目day08-07 后台Zuul网关权限验证
响应数据如下,代表成功进行了网关权限的认证.
黑马十次方项目day08-07 后台Zuul网关权限验证