.net core下訪問控制層的實現

Bug生活2048發表於2019-02-16

在上一篇.net core下對於附件上傳下載的實現主要介紹了 .net core下檔案上傳下載的相關操作,本篇主要介紹下對於許可權驗證如何通過自定義的中介軟體進行攔截實現。

對於一般的程式而言,如果在未登入的情況下理應是沒有對應的許可權訪問對應的頁面的,同時,不同的使用者也需要驗證該使用者許可權是否滿足條件。

對於後端服務來說,就需要有個中間層進行攔截,驗證對應的http請求是否滿足許可權要求。

這裡我們用到了Middleware-請求管道,通過自定義中介軟體的方式來實現對Http請求的攔截,實現相關驗證。

對於Middleware-請求管道的原理和解釋可以參考這篇文章:Middleware-請求管道的構成

實現邏輯

使用者在登入成功後,我們在服務端會自動生成一個Token,這個Token會繫結對應的許可權,同時儲存到Redis中。

我們自定義的中間層會攔截請求,獲取請求中的Token是否合法,若不合法會對該請求進行攔截。

通過使用UseMiddleware擴充套件方法,將攔截到的HttpContext進行相應的邏輯處理。

具體程式碼

首先我們自定義一個許可權控制的中介軟體,SecurityMiddleware類就是我們具體的邏輯實現。

public static IApplicationBuilder UseSecurity(this IApplicationBuilder builder)
{
    return builder.UseMiddleware<SecurityMiddleware>();
}

Startup.cs中的Configure方法下,我們新增我們自定義的中介軟體:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseSwagger();
    app.UseSwaggerUI(c => {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "我的API V1");
    });

    app.UseSecurity();//自定義中介軟體

    app.UseMvc();
}

接下來我們具體實現對應的SecurityMiddleware類,主要實現對應的Invoke方法

public async Task Invoke(HttpContext context)
{
    string path = context.Request.Path.ToString().ToLower();

    // 判斷請求的路徑是否是排除許可權限制的(如登入頁,登入頁)
    if (excludeUrl.Contains(path))
    {
        await _next(context);
        return;
    }

    // 尋找header中的token
    string userToken = string.Empty;            
    bool hasValue = context.Request.Headers.TryGetValue(INVOKER_TOKEN_HEADER, out StringValues token);
    if (!hasValue || token.Count == 0)
    {
        // 若header沒取到token,則嘗試從cookie中獲取
        userToken = context.Request.Cookies[USER_TOKEN_COOKIE_NAME];
        if(string.IsNullOrWhiteSpace(userToken))
        {
            // TODO: 尚未登入,未經授權
            await CreateUnauthorizedResponse(context);

            return;
        }
    }
    else
    {
        userToken = token[0];
    }

    //根據對應的Token到Redis中找對應的許可權資料,若沒找到,說明沒有授權
    var userInfo = await GetUserInfo(userToken);
    if (userInfo == null)
    {
        // TODO: 尚未登入,未經授權
        await CreateUnauthorizedResponse(context);
        return;
    }

    //可繼續針對請求判斷是否有相對應的許可權
}

對應構造Response方法:

private static async Task CreateUnauthorizedResponse(HttpContext context)
{
    context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
    context.Response.ContentType = "application/json;charset=utf-8";

    ResponseResult result = new ResponseResult
    {
        Result = false,
        ErrorMessage = "您需要登入後訪問此資源,請先進行登入操作。",
        Code = ResponseCode.Unauthorized
    };

    await context.Response.WriteAsync(JsonConvert.SerializeObject(result), Encoding.UTF8);
}

到這裡,我們基本上實現的對應的控制訪問。

總結

對於本篇來說,還是需要去了解下 .net core的執行原理,以便更好的去實現你想要的方法。

相關文章