【发布时间】:2012-01-24 15:38:38
【问题描述】:
我目前正试图弄清楚如何在我们的 ASP.NET 应用程序中执行手动 Windows 身份验证。问题是我们有一个 OData 服务正在运行,并使用 FormsAuthentication 提供通用登录机制并允许 OData 的 PUT 和 DELETE 动词,包括表单重定向。
但是,对于某些客户,我们集成了 Windows 身份验证,以便他们的用户与活动目录顺利集成。现在的问题是我们希望能够在不破坏 Odata 服务的情况下切换身份验证方法,因为我们依赖它。
我们正在尝试使用 IhttpModule 模仿 Windows 身份验证机制。到目前为止,我们能够打开和关闭该功能,并且在发出请求时我们会遇到挑战。我不知道的是如何使用从浏览器接收到的信息对活动目录进行身份验证:
这是我们用来从当前请求中提取 NTLM 信息的代码:
/// <summary>
/// <para>Determines whether the current <see cref="HttpRequest"/> is a NTML challenge.</para>
/// </summary>
/// <param name="request">The <see cref="HttpRequest"/> to evaluate.</param>
/// <param name="header">The output header to authenticate.</param>
/// <returns>True if the current <see cref="HttpRequest"/> is considered a NTML challenge.</returns>
protected bool IsNtlmChallenge(HttpRequest request, out string header)
{
const string headerName = @"Authorization";
if (request.Headers.AllKeys.Contains(headerName))
{
header = request.Headers[headerName];
return true;
}
header = string.Empty;
return false;
}
这允许我们从请求中提取标头。我现在需要知道的是如何在活动目录上执行身份验证。
这是我们用来提取信息的逻辑:
// Check if we need to handle authentication through Windows authentication or not.
if (WindowsAuthentication)
{
string encryptedHeader;
// If this is a challenge from the client, perform the Windows Authentication using the
// information stored inside the header.
if(IsNtlmChallenge(HttpContext.Current.Request, out encryptedHeader))
{
/* how to authenticate here with the encrypted header? */
}
HttpContext.Current.Response.AddHeader("WWW-Authenticate", "NTLM");
HttpContext.Current.Response.StatusCode = 401;
return;
}
希望有人能提供我需要的答案。
【问题讨论】:
-
好问题 - 等待好答案!
-
我怀疑是否有可能以这种方式混合表单和 Windows 身份验证。对于 winauth,您必须在 IIS 中启用它(因为 IIS 将验证这些凭据),并且 win-auth 和 forms-auth 在某些 IIS 设置(例如 IIS7+ 集成应用程序池)中不能一起工作。此外,您只能在 web.config 中指定一种身份验证模式。使用经典应用程序池时,您可以混合身份验证,但不能在相同的文件/文件夹上。如果这是您正在运行的,请在特定文件夹/文件/url 路径(例如 aspx 处理程序)上启用 win-auth,然后使用该处理程序对 win/AD 用户进行身份验证。
-
我们知道使用辅助站点,但这是最后的手段。我真的希望有人能先想出解决问题的办法。
标签: c# asp.net .net odata ntlm