iT邦幫忙

2021 iThome 鐵人賽

DAY 6
1
Modern Web

ASP.NET Web Forms 入門 - 30天建立遊艇網頁專案後端及後台功能 C#系列 第 6

Day 6 - Using ASHX File for User Authorization Management with ASP.NET Web Forms C# 使用泛型處理常式進行權限分流

=x= 🌵 網頁操作權限分流處理及 Yacht Manager - Master Page 後台主版設定。


權限分流處理介紹 :

📌 關於後台的操作權限,資料庫欄位的資料類型設為 bit 並且將預設值設為 ((0)) 代表 False,功用是在所有使用者中,操作權限為 True 者代表老闆或主管角色,只有擁有權限才可進入增刪後台使用者的頁面,其它由老闆或主管新增的後台操作人員,因為權限較低,登入後會被導引至最常使用的新聞發布頁面,並且在側邊欄不會存在使用者管理頁的選項,加上配合在主版設定使用者管理頁是否可見,可以做出讓擁有最高權限者在初次登入時,會被導引至使用者管理頁,而在網頁操作時一但點選其它功能頁,使用者管理頁的選項將消失,唯有再次登入才會導入使用者管理頁,並且利用在主版頁面建立登出清除快取功能,進一步產生登出後,阻止其它人可以使用上一頁看到使用者管理頁的個人資訊,希望能從不同角度防止一些人為操作意外。



Master Page - 權限分流實作 :

1. 關於資料庫用來作為權限管理的設定,可以參考以下圖片

https://ithelp.ithome.com.tw/upload/images/20210919/20139487N5dLKwtioD.jpg

https://ithelp.ithome.com.tw/upload/images/20210919/20139487R5X3T7u0pN.jpg


2. 建立登入頁驗證成功後會導引到的泛型處理常式 CheckAccount.ashx 在 .cs 檔加入程式碼

using System.Web;
using System.Web.Security;

namespace TayanaYachtRe.Sys
{
    /// <summary>
    /// CheckAccount 的摘要描述
    /// </summary>
    public class CheckAccount : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            // ashx 裡的 Request/Response 都要加上 context
            string ticketUserData = ((FormsIdentity)(HttpContext.Current.User.Identity)).Ticket.UserData;
            string[] ticketUserDataArr = ticketUserData.Split(';');
            bool haveRight = HttpContext.Current.User.Identity.IsAuthenticated;
            //依管理權限導頁
            if (haveRight) {
                if (ticketUserDataArr[0].Equals("True")) {
                    //以驗證票夾帶資料作為限制
                    context.Response.Redirect("User_Manager_Cpage.aspx"); //最高管理員-跳至管理員審核頁面
                }
                else {
                    context.Response.Redirect("new_list_Manager_Cpage.aspx");
                }
            }
            else {
                context.Response.Redirect("Manager_SignIn.aspx"); //導回登入頁
            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}


3. 在 Yacht Manager -Master Page 側邊欄及內容頁各加入兩個 ContentPlaceHolder 控制項

  • a. 側邊欄 ContentPlaceHolder-SidebarNormal 用來放共用功能連結。
  • b. 側邊欄 ContentPlaceHolder-SidebarUser 用來放使用者管理連結。
  • c. 主要區塊 ContentPlaceHolder-MainNormal 用來放共用功能內容。
  • d. 主要區塊 ContentPlaceHolder-MainUser 用來放使用者管理內容。

https://ithelp.ithome.com.tw/upload/images/20210919/20139487GTbX3T68Nq.jpg


4. 在 Yacht Manager - Master Page 後置程式碼 Page_Init 事件放入清除快取功能

protected void Page_Init(object sender, EventArgs e)
{
    //清除Cache,避免登出後按上一頁還會顯示Cache頁面
    Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
    Response.Cache.SetCacheability(HttpCacheability.NoCache);
    Response.Cache.SetNoStore();
}

https://ithelp.ithome.com.tw/upload/images/20210919/20139487GNcwbDrSky.jpg

  • 👺 清除快取要放在 Page_Init 才有效果。

  • 🌵 使用 Visual Studio 模擬時的預設快取為 cache-control: private,類似無痕模式,僅限個別使用者使用。

  • 👀 Page_Init 事件參考 : ASP.NET 網頁存留週期概觀

https://ithelp.ithome.com.tw/upload/images/20210919/20139487ElRSv88IZJ.jpg

5. 在 Yacht Manager - Master Page 後置程式碼 Page_Load 事件放入

protected void Page_Load(object sender, EventArgs e)
{
    //權限關門判斷 (Cookie)
    if (!HttpContext.Current.User.Identity.IsAuthenticated) {
        Response.Redirect("Manager_SignIn.aspx"); //導回登入頁
    }
    else {
        //取得驗證票夾帶資訊
        string ticketUserData = ((FormsIdentity)(HttpContext.Current.User.Identity)).Ticket.UserData;
        string[] ticketUserDataArr = ticketUserData.Split(';');
        bool haveRight = HttpContext.Current.User.Identity.IsAuthenticated;
        //依管理權限導頁
        if (haveRight) {
            if (ticketUserDataArr[0].Equals("True")) {
                //以驗證票夾帶資料作為限制,最高權限者使用時顯示使用者管理頁並切換圖示
                ManagerMenuContentPlaceHolder.Visible = true;
                ManagerMainContentPlaceHolder.Visible = true;
                ImageHead.ImageUrl = "assets/images/avatar-4.png";
                ImageMenu.ImageUrl = "assets/images/avatar-4.png";
            }
            else {
                ManagerMenuContentPlaceHolder.Visible = false;
                ManagerMainContentPlaceHolder.Visible = false;
            }
            //載入使用者個人基本資料(渲染畫面)
            LabMenuAccount.Text = ticketUserDataArr[1];
            LabMenuEmail.Text = ticketUserDataArr[3];
            LabHeadUserName.Text = ticketUserDataArr[2];
        }
    }
}
  • 🌵 將權限關門判斷放在 Master Page 就不用每一頁都寫。

6. 在 Yacht Manager - Master Page 的 .aspx 頁面的 LogOut 連結 href 位置改成 SignOut.ashx


7. 建立泛型處理常式 SignOut.ashx 並在 .cs 檔加入以下程式碼執行登出並清空相關資料

using System;
using System.Web;
using System.Web.Security;

namespace TayanaYachtRe.Sys
{
    /// <summary>
    /// SignOut 的摘要描述
    /// </summary>
    public class SignOut : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            //清除所有的 Session
            if (context.Session != null) {
                context.Session.Abandon();
                context.Session.RemoveAll();
            }

            //建立一個同名的 Cookie 來覆蓋原本的 Cookie
            HttpCookie authenticationCookie = new HttpCookie(FormsAuthentication.FormsCookieName, "");
            authenticationCookie.Expires = DateTime.Now.AddYears(-1);
            context.Response.Cookies.Add(authenticationCookie);

            // 執行登出
            FormsAuthentication.SignOut();

            // 轉向到你登出後要到的頁面
            context.Response.Redirect("Manager_SignIn.aspx", true);
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}


泛型處理常式總結 :

📢 泛型處理常式對於入門第一次遇到的人來說,看到這種看起來是中文,讀起來不像是中文的東西,會突然有點不知所措,但爬文並看完官網的介紹後,就知道可以把它當成沒有前台只有後置程式碼的網頁處理,你只要連到這個檔案,就幫你直接執行後置程式碼,看到以後就覺得超好用的啦,也有發現能用在下載功能,另外從官網的介紹可以發現還有幾個副檔名很陌生的類型,希望之後有機會能慢慢搞懂。

👀 附上微軟官網介紹 : HTTP 處理常式和 HTTP 模組概觀

  • 明日將介紹如何製作短網址功能。

上一篇
Day 5 - Using Argon2 for Password Verifying with ASP.NET Web Forms C# 使用 Argon2 驗證密碼
下一篇
Day 7 - Using Global.asax File for Short URL Routing with ASP.NET Web Forms C# 使用全域應用程式類別產生短網址路由功能
系列文
ASP.NET Web Forms 入門 - 30天建立遊艇網頁專案後端及後台功能 C#30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言