跳到主要內容

asp.net core 設定驗定權限驗證

近日來利用工作空檔,研究了asp.net core權限驗證機制, 並且透過 AuthorizationFilter 實作action 端的權限過濾。

過去在 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);//設定到期時間限制
            });


另外在 Configure 的部份,啟用Route設置以前,須註冊權限驗證模式:
            app.UseAuthentication();
            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");
            }
            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");
}


如果需要進行各種畫面的驗證,再透過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");
        }


參考來源:
https://dotblogs.com.tw/shadow/2019/01/16/105615
https://blog.johnwu.cc/article/ironman-day14-asp-net-core-filters.html










留言

這個網誌中的熱門文章

右昌的古厝、老街坊

Python 類別擴充方法

最近在使用 Python 的集合物件進行資料處理, 過程中發現某些時候,需要另外撰寫方法取得特定資料,例如 def fill_tag_data ():     for i in range ( 0 , 999 ):         tag = {}         tag[ "TagNo" ] = '5' + '{0:0>3}' .format(i)         tag[ "TagName" ] = '5' + '{0:0>3}' .format(i)         TagData.append(tag) TagData = [] # 定義為 list 集合 def first_element (pList):     if len(pList) > 0:         return pList[ 0 ]     else :         return { "TagNo" : "5000" , "TagName" : "5000" } 其中 first_element 是定義用來取得 list 的第一筆記錄的方法,需透過 first_data = first_element(TagData) 進行操作,當然也可以透過 TagData[0] ,得到第一筆記錄 但美中不足的是,我們必須確定 TagData 這個 list 的長度大於 0 ,才能夠取得 TagData[0] 因此在取回 TagData[0] 以前,會另外撰寫判別式 if(len(TagData)>0):      none 於是...

大社老街屋巡禮

  這座三合院的馬背雕飾蠻細工的 上面兩幢的側牆馬背,都有特別的雕飾,這是常見的三合院風格 在我走回程往我家的方向,又看到幾座大院,後頭都是現代化的樓房 這座三合院蠻有規模的,院子邊還有一座古井,也很有歷史了 這是舊三合院的側屋殘壁,屋頂損壞後就沒再修護了 三合院的側牆 走到了三奶里,這邊就有三座古厝 大社最有名的巫家老厝,老厝是在大社的市中心,黃昏市場外面 老厝的院子保存的很完整 大院的右側一角 老厝的左側小旁門 巫家老厝外院 這座古厝在大社三奶里也蠻有名的 大瓦厝的側邊外牆 房子外牆很典雅,搭配裡面有層次的老建物 房子後頭的一塊小田地,有點像我以前屏東阿嬤家的古厝風格 這個景色很像油畫上面看到的,這區塊的古厝週邊都蓋滿了樓房 走到了大社觀音里後可以看到密集的巷弄老房 巷底的老房子,窗戶上緣有雕花裝飾 老三合院的正廳 巷弄邊老房子一角 在街上看到老房子常常有這個廣告 老巷弄與老房,搭配著新跑車 觀音里的老巷弄三合院