近日來利用工作空檔,研究了asp.net core權限驗證機制, 並且透過 AuthorizationFilter 實作action 端的權限過濾。
在.net core的部份,權限設置已經較為簡化,但仍有需要注意的「眉角」:
首先在Startup.cs 的 ConfigureServices,必須設置系統授權的有效時間,以及指定登入登出頁面:
執行系統登出:
如果需要進行各種畫面的驗證,再透過Filter Attribute
參考來源:
https://dotblogs.com.tw/shadow/2019/01/16/105615
https://blog.johnwu.cc/article/ironman-day14-asp-net-core-filters.html
過去在 asp.net 的mvc 有類似的做法,在asp.net core 其實也是大同小異。
asp.net mvc 也一樣是透過ActionFilter 處理權限過濾,Sam是透過cookie將加密資訊進行記錄。
這裡Account 是登錄的使用者帳號資訊,記錄於UserAuth,並且設置有效時間為1小時
var hc = new HttpCookie("UserAuth",Account)
{
Expires = DateTime.Now.AddHours(1),
HttpOnly = true
};
Response.Cookies.Add(hc);
在.net core的部份,權限設置已經較為簡化,但仍有需要注意的「眉角」:
首先在Startup.cs 的 ConfigureServices,必須設置系統授權的有效時間,以及指定登入登出頁面:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(option=>
{
option.LoginPath = new PathString("/Login/Index"); //設定登入頁Action
option.LogoutPath = new PathString("/Home/Index");//設定登出頁Action
//設定cookie 有效時間,這部份也可以在登入的時候進行設置
option.ExpireTimeSpan = TimeSpan.FromMinutes(60);//設定到期時間限制
});
.AddCookie(option=>
{
option.LoginPath = new PathString("/Login/Index"); //設定登入頁Action
option.LogoutPath = new PathString("/Home/Index");//設定登出頁Action
//設定cookie 有效時間,這部份也可以在登入的時候進行設置
option.ExpireTimeSpan = TimeSpan.FromMinutes(60);//設定到期時間限制
});
另外在 Configure 的部份,啟用Route設置以前,須註冊權限驗證模式:
最後執行系統登入事件處理:
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
最後執行系統登入事件處理:
[AspNetCoreMvc1.Framework.Filter.AllowAnonoymusAttribute]
public async Task<IActionResult> Logon(string txtUid, string txtPwd)
{
//帳密驗證要先處理,這裡直接假設通過後的處理原則
if(!CheckUser(txtUid, txtPwd)){
ViewBag.ErrMsg = "帳密錯誤!!";
return RedirectToAction("Index","Login");
}
ViewBag.ErrMsg = "帳密錯誤!!";
return RedirectToAction("Index","Login");
}
Claim[] claims = {new Claim("Account", txtUid) }; //取名Account
ClaimsIdentity claimsIdentity = new ClaimsIdentity(claims , CookieAuthenticationDefaults.AuthenticationScheme);//Scheme必填
ClaimsPrincipal principal = new ClaimsPrincipal(claimsIdentity);
var authProperties = new AuthenticationProperties{};
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authProperties);
var newclims = HttpContext.User.Claims;
return RedirectToAction("Index","Home");
}
執行系統登出:
//處理系統登出
public async Task<IActionResult> Logout()
{
await HttpContext.SignOutAsync();
return RedirectToAction("Index","Login");
}
public async Task<IActionResult> Logout()
{
await HttpContext.SignOutAsync();
return RedirectToAction("Index","Login");
}
如果需要進行各種畫面的驗證,再透過Filter Attribute
public sealed class LoginAuthorizeAttribute : Attribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationFilterContext context)
{
if(!AuthorizeSessionNavigate(context))
{
context.Result = new RedirectToRouteResult(new
RouteValueDictionary(new{
Controller="Login",
Action="Index"
}));
}
}
private bool AuthorizeSessionNavigate(AuthorizationFilterContext context)
{
if(context.HttpContext.User.Claims.Where(m=>m.Type ==
"Account").Count()>0){
return true;
}
return false;
}
}//end filter class
在需要進行驗證的Action ,增加filter attribute
[AspNetCoreMvc1.Framework.Filter.LoginAuthorize]
//執行系統登出
public async Task<IActionResult> Logout()
{
await HttpContext.SignOutAsync();
return RedirectToAction("Index","Login");
}
{
public void OnAuthorization(AuthorizationFilterContext context)
{
if(!AuthorizeSessionNavigate(context))
{
context.Result = new RedirectToRouteResult(new
RouteValueDictionary(new{
Controller="Login",
Action="Index"
}));
}
}
private bool AuthorizeSessionNavigate(AuthorizationFilterContext context)
{
if(context.HttpContext.User.Claims.Where(m=>m.Type ==
"Account").Count()>0){
return true;
}
return false;
}
}//end filter class
在需要進行驗證的Action ,增加filter attribute
[AspNetCoreMvc1.Framework.Filter.LoginAuthorize]
//執行系統登出
public async Task<IActionResult> Logout()
{
await HttpContext.SignOutAsync();
return RedirectToAction("Index","Login");
}
參考來源:
https://dotblogs.com.tw/shadow/2019/01/16/105615
https://blog.johnwu.cc/article/ironman-day14-asp-net-core-filters.html
留言
張貼留言