我必须使用窗体身份验证,而不是Windows身份验证来访问一个ASP.NET站点ActiveDirectoryMembershipProvider
。 因为他们需要一个设计输入形式,而不是Windows身份验证使用浏览器弹出认证的网站必须使用的形式。
该网站需要模拟用户通过Active Directory访问用户专用文件登录。
然而, WindowsIdentity.GetCurrent()
是不一样的HttpContext.Current.User.Identity
虽然我的web.config中包含:
<authentication mode="Forms">
<forms loginUrl="login.aspx" timeout="480"/>
</authentication>
<identity impersonate="true" />
我不能使用LoginUser()
和WindowsIdentity.Impersonate()
因为我需要模拟的AD用户得到他们的特定权限,我不知道用户的密码,因为形式负责采伐英寸
是否有可能,也许从login.aspx.cs,采取System.Web.UI.WebControls.Login.Password
,然后保存LoginUser()
令牌会话变量WindowsIdentity.Impersonate()
以后呢? 或者,也许冒充的正确方法的一个更安全的方法?
我很困惑,为什么窗体身份验证不能自动<identity impersonate="true" />
我读过这http://msdn.microsoft.com/en-us/library/ms998351.aspx但它使用Windows身份验证。
冒充使用窗体身份验证,用户可以做到的。 下面的代码做的工作 。
在Visual Studio的杂志文章罗伯特称作是一个很好的资源。 这里有一些问题,本文中的示例代码,所以我提供了以下一些工作的代码。
注:如果您使用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。
UPDATE2:
我不知道这是为什么得到downvoted,因为它的工作原理。 我已经添加了PInvoke的签名和一些测试代码。 此外,使用“ 以管理员身份运行 ”推出的Visual Studio。 谷歌如何做到这一点,如果你不知道怎么办。
如果用户使用的是IE,那么你可以打开集成安全的网站和您的用户进行身份验证默默(没有登录对话框,没有登录页)。 然后,您的模拟将工作。 如果您需要针对其他浏览器,那么这可能无法正常工作(用户可能会使用一个登录对话框,提示)。
因为你的用户使用比自己的域帐户以外的帐户登录您当前的模拟行不通。 你不能指望该网站冒充还没有给自己的凭据的用户。 这将违背基本的安全主体。
你会发现这个有用:
- 如何创建一个登录界面,让管理员用户登录为用户数据库的另一个用户
编辑
在更紧密地阅读你的问题,我不知道,如果这种做法将与您虽然工作的情况; 当你登录使用表单认证和冒充的Active Directory用户
最近,我们得到了同样的问题,客户希望其用户可以通过AD帐户登录,然后这个证书必须被用来访问分析服务以及所有其他数据库。 他们希望这样的说法,因为他们实施审计系统和所有访问都必须通过帐户的当前登录来完成。
我们试图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打开您的解决方案
然后在包控制台运行安装,包装51Degrees.mobi
然后,它会增加51Degrees到您的网站。 然后,您可以在您的应用数据编辑51Degrees.mobi.config删除重定向部分。
现在,您将拥有最新的浏览器功能