首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> 關於ASP.NET

ASP.NET 表單驗證與授權實戰範例:登入頁面、驗證邏輯與 Web.config 設定

     編輯:關於ASP.NET

登入頁面 (Login.aspx) 完整標記

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Login.aspx.cs" Inherits="Login" %>
<!DOCTYPE html>
<html><head><title>使用者登入</title></head>
<body>
  <form id="form1" runat="server">
    <div style="max-width:400px;margin:50px auto;padding:20px;border:1px solid #ddd;border-radius:4px;">
      <h2>登入系統</h2>
      <div style="margin-bottom:15px;">
        <asp:Label ID="lblUser" runat="server" Text="使用者帳號:" AssociatedControlID="txtUser" CssClass="form-label" /><br />
        <asp:TextBox ID="txtUser" runat="server" CssClass="form-control" />
        <asp:RequiredFieldValidator ID="rfvUser" runat="server" ControlToValidate="txtUser"
            ErrorMessage="帳號不可空白" Display="Dynamic" CssClass="text-danger" />
      </div>
      <div style="margin-bottom:15px;">
        <asp:Label ID="lblPwd" runat="server" Text="密碼:" AssociatedControlID="txtPwd" CssClass="form-label" /><br />
        <asp:TextBox ID="txtPwd" runat="server" TextMode="Password" CssClass="form-control" />
        <asp:RequiredFieldValidator ID="rfvPwd" runat="server" ControlToValidate="txtPwd"
            ErrorMessage="密碼不可空白" Display="Dynamic" CssClass="text-danger" />
      </div>
      <div style="margin-bottom:15px;">
        <asp:CheckBox ID="chkRemember" runat="server" Text="記住我 (持久性 Cookie)" />
      </div>
      <asp:Button ID="btnLogin" runat="server" Text="登入" CssClass="btn btn-primary" OnClick="btnLogin_Click" ValidationGroup="Login" />
      <asp:ValidationSummary ID="vsLogin" runat="server" ValidationGroup="Login" HeaderText="請修正以下錯誤:" CssClass="alert alert-danger" />
    </div>
  </form>
</body></html>

登入驗證邏輯

using System;
using System.Data.SqlClient;
using System.Web.Security;
using System.Web.UI;

public partial class Login : Page
{
    protected void btnLogin_Click(object sender, EventArgs e)
    {
        if (!Page.IsValid) return;

        string user = txtUser.Text.Trim();
        string pwd = txtPwd.Text;

        // 1. 驗證帳密 (範例簡化,實務應用雜湊比對)
        if (ValidateUser(user, pwd))
        {
            // 2. 取得角色 (實務從 DB 讀取)
            string roles = GetUserRoles(user); // 如 "Admin,Editor"

            // 3. 建立驗證票據
            var ticket = new FormsAuthenticationTicket(
                1, user, DateTime.Now, DateTime.Now.AddMinutes(30),
                chkRemember.Checked, roles, FormsAuthentication.FormsCookiePath);

            // 4. 加密寫入 Cookie
            string encTicket = FormsAuthentication.Encrypt(ticket);
            var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket)
            {
                HttpOnly = true,
                Secure = FormsAuthentication.RequireSSL
            };
            if (chkRemember.Checked) cookie.Expires = ticket.Expiration;
            Response.Cookies.Add(cookie);

            // 5. 導向
            Response.Redirect(FormsAuthentication.GetRedirectUrl(user, chkRemember.Checked));
        }
        else
        {
            lblError.Text = "帳號或密碼錯誤";
        }
    }

    private bool ValidateUser(string username, string password)
    {
        // 實務:參數化查詢 + 密碼雜湊驗證 (BCrypt/PBKDF2)
        string connStr = System.Configuration.ConfigurationManager.ConnectionStrings["MyDb"].ConnectionString;
        using (var conn = new SqlConnection(connStr))
        using (var cmd = new SqlCommand("SELECT PasswordHash, PasswordSalt FROM Users WHERE UserName=@User", conn))
        {
            cmd.Parameters.AddWithValue("@User", username);
            conn.Open();
            using (var reader = cmd.ExecuteReader())
            {
                if (reader.Read())
                {
                    string hash = reader.GetString(0);
                    string salt = reader.GetString(1);
                    return HashHelper.Verify(password, hash, salt); // 自訂驗證方法
                }
            }
        }
        return false;
    }

    private string GetUserRoles(string username)
    {
        // 從 DB 讀取角色字串
        return "User"; // 簡化
    }
}

Web.config 驗證與授權設定

<configuration>
  <connectionStrings>
    <add name="MyDb" connectionString="Server=.;Database=WebSolution;Integrated Security=True" providerName="System.Data.SqlClient" />
  </connectionStrings>

  <system.web>
    <!-- 1. 啟用表單驗證 -->
    <authentication mode="Forms">
      <forms name=".AUTHCOOKIE"
             loginUrl="Login.aspx"
             timeout="30"
             path="/"
             protection="All"
             requireSSL="false"
             slidingExpiration="true" />
    </authentication>

    <!-- 2. 預設授權規則:拒絕匿名 -->
    <authorization>
      <deny users="?" />
    </authorization>

    <!-- 3. 公開頁面允許匿名 -->
    <location path="Login.aspx">
      <system.web>
        <authorization>
          <allow users="*" />
        </authorization>
      </system.web>
    </location>
    <location path="Register.aspx">
      <system.web>
        <authorization>
          <allow users="*" />
        </authorization>
      </system.web>
    </location>

    <!-- 4. 管理區域僅限 Admin 角色 -->
    <location path="Admin">
      <system.web>
        <authorization>
          <allow roles="Admin" />
          <deny users="*" />
        </authorization>
      </system.web>
    </location>
  </system.web>
</configuration>

Global.asax 還原角色 Principal (必要)

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
    HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
    if (authCookie == null) return;

    FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);
    if (ticket == null || ticket.Expired) return;

    string[] roles = ticket.UserData.Split(',', StringSplitOptions.RemoveEmptyEntries);
    FormsIdentity identity = new FormsIdentity(ticket);
    GenericPrincipal principal = new GenericPrincipal(identity, roles);
    Context.User = principal;
}

受保護頁面使用授權

<%@ Page Language="C#" %>
<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        if (User.IsInRole("Admin"))
        {
            pnlAdmin.Visible = true;
        }
        lblUser.Text = $"歡迎, {User.Identity.Name} (角色: {string.Join(",", ((System.Security.Principal.GenericPrincipal)User).Roles)})";
    }
</script>
<html><body>
  <asp:Label ID="lblUser" runat="server" /><br />
  <asp:Panel ID="pnlAdmin" runat="server" Visible="false">管理功能區塊</asp:Panel>
</body></html>

關鍵設定說明

設定用途
forms nameCookie 名稱,避免多應用程式衝突
loginUrl未驗證導向頁面
timeout票據有效分鐘數 (slidingExpiration=true 時為滑動過期)
protection="All"加密 + 驗證 (防竄改)
requireSSL生產環境必須 true,確保 Cookie 只在 HTTPS 傳輸
authorization deny users="?"預設拒絕匿名,實現「預設拒絕」安全原則
location path針對特定路徑覆寫授權規則

總結

ASP.NET 表單驗證授權完整鏈路:登入頁驗證 → `FormsAuthenticationTicket` 含角色 → 加密 Cookie → `Global.asax` 還原 `GenericPrincipal` → `web.config` `` / 程式碼 `User.IsInRole` 控制存取。範例提供可直接參考的登入頁、驗證邏輯、Web.config 設定與 Global.asax 關鍵程式碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved