[英]Impersonate using Forms Authentication
我有一個ASP.NET站點,該站點必須使用表單身份驗證而不是Windows身份驗證來訪問ActiveDirectoryMembershipProvider
。 該站點必須使用表單,因為它們需要設計的輸入表單,而不是Windows身份驗證使用的瀏覽器身份驗證彈出窗口。
該站點需要模擬通過Active Directory登錄的用戶,以訪問用戶特定的文件。
但是,盡管我的web.config包含以下內容,但WindowsIdentity.GetCurrent()
與HttpContext.Current.User.Identity
是不同的:
<authentication mode="Forms">
<forms loginUrl="login.aspx" timeout="480"/>
</authentication>
<identity impersonate="true" />
我無法使用LoginUser()
和WindowsIdentity.Impersonate()
因為我需要模擬為AD用戶來獲取其特定權限,並且我不知道用戶的密碼,因為Forms負責登錄。
是否有可能從login.aspx.cs中獲取System.Web.UI.WebControls.Login.Password
,然后將LoginUser()
令牌保存在WindowsIdentity.Impersonate()
的會話變量中? 還是模擬正確方法的更安全的方法?
我很困惑為什么Forms身份驗證不能自動<identity impersonate="true" />
我已經閱讀了此http://msdn.microsoft.com/zh-cn/library/ms998351.aspx,但是它使用Windows身份驗證。
可以使用表單身份驗證模擬用戶。 以下代碼可以正常工作 。
Robert提到的Visual Studio Magazine文章是很好的資源。 本文中的示例代碼存在一些問題,因此我在下面提供了一些工作代碼。
注意:如果您使用的是Visual Studio,請確保以“ 以管理員身份運行 ”啟動它,以避免UAC阻止模擬的問題。
// in your login page (hook up to OnAuthenticate event)
protected void LoginControl_Authenticate(object sender, AuthenticateEventArgs e)
{
int token;
// replace "YOURDOMAIN" with your actual domain name
e.Authenticated = LogonUser(LoginUser.UserName,"YOURDOMAIN",LoginUser.Password,8,0,out token);
if (e.Authenticated) {
Session.Add("principal", new WindowsPrincipal(new WindowsIdentity(new IntPtr(token))));
}
}
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword,
int dwLogonType, int dwLogonProvider, out int TokenHandle);
// in global.asax.cs
void Application_PreRequestHandlerExecute(object send, EventArgs e)
{
if (Thread.CurrentPrincipal.Identity.IsAuthenticated == true && HttpContext.Current.Session != null) {
WindowsPrincipal windowsPrincipal = (WindowsPrincipal)Session["principal"];
Session["principal"] = (GenericPrincipal)Thread.CurrentPrincipal;
Thread.CurrentPrincipal = windowsPrincipal;
HttpContext.Current.User = windowsPrincipal;
HttpContext.Current.Items["identity"] = ((WindowsIdentity)windowsPrincipal.Identity).Impersonate();
}
}
// in global.asax.cs
void Application_PostRequestHandlerExecute(object send, EventArgs e)
{
if (HttpContext.Current.Session != null && Session["principal"] as GenericPrincipal != null) {
GenericPrincipal genericPrincipal = (GenericPrincipal)Session["principal"];
Session["principal"] = (WindowsPrincipal)Thread.CurrentPrincipal;
Thread.CurrentPrincipal = genericPrincipal;
HttpContext.Current.User = genericPrincipal;
((WindowsImpersonationContext)HttpContext.Current.Items["identity"]).Undo();
}
}
// test that impersonation is working (add this and an Asp:Label to a test page)
protected void Page_Load(object sender, EventArgs e)
{
try {
// replace YOURSERVER and YOURDB with your actual server and database names
string connstring = "data source=YOURSERVER;initial catalog=YOURDB;integrated security=True";
using (SqlConnection conn = new SqlConnection(connstring)) {
conn.Open();
SqlCommand cmd = new SqlCommand("SELECT SUSER_NAME()", conn);
using (SqlDataReader rdr = cmd.ExecuteReader()) {
rdr.Read();
Label1.Text = "SUSER_NAME() = " + rdr.GetString(0);
}
}
}
catch {
}
}
更新:
您還應該處理Application_EndRequest
,因為像Response.End()
這樣的調用將繞過Application_PostRequestHandlerExecute
。
另一個問題是WindowsIdentity可能會收集垃圾,因此您應在每次請求時從登錄令牌中創建一個新的WindowsIdentity和WindowsPrincipal。
更新2:
我不知道為什么這會被否決,因為它有效。 我添加了pinvoke簽名和一些測試代碼。 再次,使用“ 以管理員身份運行 ”啟動Visual Studio。 Google如果不知道該怎么做。
如果您的用戶使用的是IE,則可以打開網站的集成安全性,並且您的用戶將通過靜默方式進行身份驗證(沒有登錄對話框,沒有登錄頁面)。 這樣您的模仿就可以了。 如果您需要定位其他瀏覽器,則可能無法正常工作(可能會向用戶顯示一個登錄對話框)。
您當前的模擬將永遠無法工作,因為您的用戶使用其域帳戶以外的帳戶登錄。 您不能指望該網站會冒充沒有提供其憑據的用戶。 這將違反基本的安全原則。
您可能會發現這很有用:
編輯
在仔細閱讀您的問題時,我不確定該方法是否適用於您的情況。 當您使用表單身份驗證登錄並模擬Active Directory用戶時
最近,我們遇到了同樣的問題,客戶希望他們的用戶可以通過AD帳戶登錄,然后必須使用此憑據來訪問Analysis Service以及所有其他數據庫。 他們之所以希望如此,是因為他們實施了審核系統,並且所有訪問都必須由當前登錄的帳戶完成。
我們嘗試了Forms身份驗證和Win32 LogonUser()API來模擬部分,它雖然有效,但它還要求我們提供純文本形式的用戶密碼。 后來,我們決定使用Windows身份驗證,它節省了很多時間(不再需要AD身份驗證,而是手動模擬)。 當然,也沒有精美的登錄頁面。
為了以防萬一,並且有點晚了,我發現了一些對我有用的東西,這確實很簡單,但當然僅用於測試目的...
只需使用您的用戶名設置一個cookie。
//Login button. You can give whatever input to the form
protected void Login_Click(object sender, EventArgs e)
{
FormsAuthentication.SetAuthCookie("your_username", createPersistentCookie: true);
Response.Redirect("~/");
}
接受任何評論...
在Visual Studio中安裝NuGet打開您的解決方案
然后在程序包控制台中運行Install-Package 51Degrees.mobi
然后它將51Degrees添加到您的網站。 然后,您可以在應用數據中編輯51Degrees.mobi.config,以刪除重定向部分。
您現在將擁有最新的瀏覽器功能
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.