在上一篇[.net core下對于附件上傳下載的實(shí)現(xiàn)]主要介紹了 .net core下文件上傳下載的相關(guān)操作士葫,本篇主要介紹下對于權(quán)限驗證如何通過自定義的中間件進(jìn)行攔截實(shí)現(xiàn)巩掺。
對于一般的程序而言濒持,如果在未登錄的情況下理應(yīng)是沒有對應(yīng)的權(quán)限訪問對應(yīng)的頁面的茉继,同時谎脯,不同的用戶也需要驗證該用戶權(quán)限是否滿足條件不见。
對于后端服務(wù)來說澳化,就需要有個中間層進(jìn)行攔截,驗證對應(yīng)的http請求是否滿足權(quán)限要求稳吮。
這里我們用到了Middleware-請求管道缎谷,通過自定義中間件的方式來實(shí)現(xiàn)對Http請求的攔截,實(shí)現(xiàn)相關(guān)驗證灶似。
對于Middleware-請求管道的原理和解釋可以參考這篇文章:Middleware-請求管道的構(gòu)成
實(shí)現(xiàn)邏輯
用戶在登錄成功后列林,我們在服務(wù)端會自動生成一個Token
,這個Token
會綁定對應(yīng)的權(quán)限酪惭,同時保存到Redis中希痴。
我們自定義的中間層會攔截請求,獲取請求中的Token
是否合法春感,若不合法會對該請求進(jìn)行攔截砌创。
通過使用UseMiddleware
擴(kuò)展方法虏缸,將攔截到的HttpContext
進(jìn)行相應(yīng)的邏輯處理。
具體代碼
首先我們自定義一個權(quán)限控制的中間件,SecurityMiddleware
類就是我們具體的邏輯實(shí)現(xiàn)嫩实。
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();
}
接下來我們具體實(shí)現(xiàn)對應(yīng)的SecurityMiddleware
類,主要實(shí)現(xiàn)對應(yīng)的Invoke
方法
public async Task Invoke(HttpContext context)
{
string path = context.Request.Path.ToString().ToLower();
// 判斷請求的路徑是否是排除權(quán)限限制的(如登錄頁舶赔,登錄頁)
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: 尚未登錄谦秧,未經(jīng)授權(quán)
await CreateUnauthorizedResponse(context);
return;
}
}
else
{
userToken = token[0];
}
//根據(jù)對應(yīng)的Token到Redis中找對應(yīng)的權(quán)限數(shù)據(jù)竟纳,若沒找到,說明沒有授權(quán)
var userInfo = await GetUserInfo(userToken);
if (userInfo == null)
{
// TODO: 尚未登錄疚鲤,未經(jīng)授權(quán)
await CreateUnauthorizedResponse(context);
return;
}
//可繼續(xù)針對請求判斷是否有相對應(yīng)的權(quán)限
}
對應(yīng)構(gòu)造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 = "您需要登錄后訪問此資源锥累,請先進(jìn)行登錄操作。",
Code = ResponseCode.Unauthorized
};
await context.Response.WriteAsync(JsonConvert.SerializeObject(result), Encoding.UTF8);
}
到這里集歇,我們基本上實(shí)現(xiàn)的對應(yīng)的控制訪問桶略。
總結(jié)
對于本篇來說,還是需要去了解下 .net core的運(yùn)行原理诲宇,以便更好的去實(shí)現(xiàn)你想要的方法际歼。