ASP.NET 讀取使用者登入帳號:User.Identity vs LogonUserIdentity
1 | 3,797 |
在 2023 討論 ASP.NET WebForm,有點像大家都在聊海拉魯,你卻在研究瑪俐歐要怎麼救公主,邊緣感十足。但這個茶包讓我踩了好幾次雷,想想還是寫一篇紀念一下。
要在 ASP.NET 取得登入網站的使用者帳號,我們有不少舊程式是用 Request.LogonUserIdentity.Name 取值,運作多年相安無事,不覺得有什麼問題。但在測試台因特殊需求改用 Form 驗證(表單驗證)之後,問題一一浮現。
這裡借用之前文章的 Form 驗證程式小做修改,在頁面顯示 User.GetType().Name、Request.LogonUserIdentity.Name、User.Identity.Name 對照,進行實測驗證。
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<h3>WebForm</h3>
<div>
User.GetType().Name = <%= User.GetType().Name %> <br />
Request.LogonUserIdentity.Name = <%= Request.LogonUserIdentity.Name %> <br />
User.Identity.Name = <%= User.Identity.Name %>
</div>
<a href="ShowUser.ashx">ShowUser.ashx</a>
<a href="Logout.aspx">Logout.aspx</a>
</form>
</body>
</html>
先設定 Windows 整合式驗證,此時 HttpContext.Current.User 物件型別為 WindowsPrincipal,Request.LogonUserIdentity 與 User.Identity 結果相同,換言之,若 IIS 走 Windows 驗證,兩種寫法都能正確抓到使用者登入帳號:
切換到 Form 驗證,結果就不同了,User 型別變成 GenericPrincipal,但 Request.LogonUserIdentity 顯示的是 IIS AppPool 執行身分,User.Identity 傳回的才是 Form 驗證的登入帳號:
LogonUserIdentity 之所以能正確運行沒出問題,是因為原本的開發測試環境及線上環境都是使用 Windows 整合式驗證;要同時支援 Windows 驗證及 Form 驗證,請使用 User.Identity。
Experiment to illustrate the difference between User.Identity and Request.LogonUserIdentity in Windows and form authentications.
Comments
# by Huang
一開始就只學Form驗證,也只學會使用User.Identity...XD