微服務網關實戰05-網關鑑權

在微服務的架構中,有一個東西非常重要,那就是鑑權,先簡單介紹一下這個鑑權是什麼。

我們對外提供接口,那並不代表着每個人都有權力訪問接口,此時就需要對接口進行限制訪問。一般的做法就是給訪問接口的人發放一個令牌token,一般情況下把token放在header上面,每次請求的時候,都帶着這個token。

微服務網關實戰05-網關鑑權

 

在本章節中,我們模擬token請求及校驗,在filter包中添加鑑權類,如下:

SecurityFiltter鑑權類

/**
 * All rights Reserved, Designed By OprCalf
 * Copyright:    Copyright(C) 2016-2020
 * Company       LengYin Ltd.
 */

package com.platform.gateway.common.filter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import com.google.common.base.Strings;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.platform.gateway.common.utils.MsgUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * @projectName:  platform-gateway-demo
 * @package:      com.platform.gateway.common.filters
 * @className:    SecurityFiltter.java
 * @description:  鑑權過濾
 * @author:       OprCalf
 * @date:         2020年3月9日
 */
@Slf4j
@Component
public class SecurityFiltter extends ZuulFilter {

    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return Integer.MIN_VALUE + 3;
    }

    @Override
    public boolean shouldFilter() {
        final RequestContext ctx = RequestContext.getCurrentContext();
        // 當發生異常的時候,不是進行取值
        if (ctx.getThrowable() != null) {
            log.error("{}", ctx.getThrowable().fillInStackTrace());
            if (ctx.sendZuulResponse()) {
                return true;
            } else {
                return false;
            }
        } else {
            return true;
        }
    }

    @Override
    public Object run() throws ZuulException {
        final RequestContext ctx = RequestContext.getCurrentContext();
        final HttpServletRequest request = ctx.getRequest();
        final HttpServletResponse response = ctx.getResponse();
        try {
            final String token = request.getHeader("access_token");
            if (Strings.isNullOrEmpty(token)) {
                ctx.setSendZuulResponse(false);
                ctx.setResponseStatusCode(HttpStatus.FORBIDDEN.value());
                response.setContentType("application/json;charset=UTF-8");
                response.getOutputStream().write(MsgUtils.buildFailureMsg("當前請求沒有token").toString().getBytes("utf-8"));
            } else {
                final String tokenValue = "nc3yb4x9n24nty23nu034bry9cy359-x23n4-x";
                if (!tokenValue.equals(token)) {
                    ctx.setSendZuulResponse(false);
                    ctx.setResponseStatusCode(HttpStatus.FORBIDDEN.value());
                    response.setContentType("application/json;charset=UTF-8");
                    response.getOutputStream()
                            .write(MsgUtils.buildFailureMsg("當前token不正確").toString().getBytes("utf-8"));
                }
            }
            return null;
        }
        catch (final Exception e) {
            log.error("{}", e.fillInStackTrace());
        }
        return null;
    }

}

這樣就完成了簡單的token校驗,接下來我們來進行實驗

不帶token的實驗

微服務網關實戰05-網關鑑權

不帶token

當我們不帶token的時候,會提示我們的請求沒有token,不給我們訪問接口,實驗成功。

帶錯誤token的實驗

微服務網關實戰05-網關鑑權

帶錯誤token

當我們訪問帶上錯誤的token的時候,會提示token錯誤,不能訪問接口,實驗成功。

帶正確token的實驗

微服務網關實戰05-網關鑑權

帶上正確的token

此時我們帶上了正確的token,訪問是成功的。

總結:在本次的鑑權中,只是模擬了token的鑑權,本質上原理如此,生產中,會結合redis,把token放在redis上面,做超時處理,同時還會對token做更加複雜的正確與否處理。

最後,謝謝觀賞,覺得好的話,點個贊,有什麼問題可以留言溝通,麼麼噠。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章