【原創】Spring-Cloud架構入門(三)網關與服務鑑權方案--轉載請註明出處

一、網關Zuul

SpringCloud的Zuul組件,爲我們提供了路由轉發的功能,同時在路由過程中,還可以進行日誌打印,權限控制等功能。日誌打印以及權限控制可以通過實現ZuulFilter來進行:

package com.zhou.config;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

@Component
public class MyFilter extends ZuulFilter {

    /**
     * 返回一個字符串代表過濾器的類型,在zuul中定義了四種不同生命週期的過濾器類型,具體如下:
     * pre 路由之前
     * routing 路由之時
     * post 路由之後
     * error 發生錯誤時
     * 常亮可以查看 FilterConstants
     */
    @Override
    public String filterType() {
        return "pre";
    }

    /**
     * 過濾器的過濾順序
     */
    @Override
    public int filterOrder() {
        return 0;
    }

    /**
     * 這裏可以寫邏輯判斷,是否要過濾,true,永遠過濾。
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 過濾器的具體邏輯。可用很複雜,包括查sql,nosql去判斷該請求到底有沒有權限訪問。
     */
    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        System.out.println(request.getRequestURI());
        System.out.println(request.getRequestURL());
        Object accessToken = request.getParameter("token");
        if(accessToken == null) {
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(401);
            try {
                ctx.getResponse().getWriter().write("token is empty");
            }catch (Exception e){}

            return null;
        }
        return null;
    }
}

上面的代碼中,就進行了一個最簡單的權限校驗功能(實際的權限控制比這個複雜的多,下面會詳細講解)。通過Filter,還可以在網關層進行日誌打印的功能,但是在日誌打印時,需要注意我們進行打印請求頭與響應體時,需要從Request和Response中獲取IO流來進行打印,而普通IO是無法進行復用的,因此,需要注意在打印日誌時,需要將文件下載上傳類的接口過濾,以避免文件內容爲空的問題。

二、網關層服務鑑權方案

網關層服務鑑權方案屬於一種比較常見的服務鑑權方案,在權限需要靈活配置的情況下用此方案比較好,該方案的優勢在於不與業務代碼耦合,是否開放接口,可以通過後臺進行設置,而不需要去變更代碼。

權限綁定關係:url -> 前端Model -> 權限包集合 -> 用戶角色

下方流程圖即爲鑑權流程:

在上圖中,任何用戶訪問後臺需要經過以下步驟:

1.請求被網關層攔截

2.網關層請求鑑權服務進行鑑權,查看是否具有權限,不具備權限則將其攔截

3.網關層轉發至服務層

同時,權限的url變更,只需要由後臺人員對鑑權服務中的數據進行變更即可,不需要變更後端的服務代碼,同時,後端的服務業務開發人員也不需要關注權限url的變更。

三、Controller層AOP鑑權

Controller層AOP鑑權與網關層鑑權有所不同,其權限綁定結構相比網關層鑑權,減少了一層url層的數據。

權限綁定關係:前端Model -> 權限包集合 -> 用戶角色

同時,該方式鑑權優勢也具有劣勢。

1.劣勢

要求被權限保護的接口不能被微服務內部訪問,否則會造成重複鑑權。

會導致權限與AOP的註解代碼綁死,如果希望取消某個接口的權限,或者新增某個接口的權限,就需要對AOP的註解代碼進行變更。

2.優勢

可以將參數納入權限控制。例如:用戶A只具有“杭州”的數據的訪問權限,那麼就需要將請求參數納入到鑑權的範圍中,但是接口的參數模型是不一樣的,此時利用AOP註解就可以進行輕鬆的鑑權配置,而網關層不行。

可以減少配置的權限數量,並且去掉url層的權限數據,直接在AOP註解上配置前端Model層的權限信息。

四、總結

目前,在我周圍使用SpringCloud的公司中,分採用網關層鑑權的方案進行鑑權的較多,但是兩種方案本身是各有優劣的,並沒有實際的孰好孰壞。

其實本質上,權限的校驗方案本身都比較通用化,但是因爲權限本身,需要對大量的接口進行攔截處理,並且,每次鑑定權限在無緩存支撐的情況下,會每一次查詢多張數據庫表,吃掉大量的服務器性能。因此,在進行鑑權系統的開發時,無論採用哪一種方案,做好適當的多級緩存,纔是重中之重。

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