如何使用 WindowsIdentity 和 SQL Server 集成安全设置表单身份验证
Posted
技术标签:
【中文标题】如何使用 WindowsIdentity 和 SQL Server 集成安全设置表单身份验证【英文标题】:How to setup Forms Authentication with WindowsIdentity and SQL Server Integrated Security 【发布时间】:2009-09-24 19:14:22 【问题描述】:这是我们当前的设置。我们配置了 Active Directory(域名为 mis1)来处理我们所有的身份验证问题。我们为 impersonation=true 设置了 Web 应用程序,以便我们可以在用户登录时调用数据库查询。对于这个特定的应用程序,IIS 设置为匿名访问,我们可以进行表单身份验证。
为了我们的数据库安全,我们在数据库服务器上设置了本地组,并根据应用程序的需要将用户添加到这些组中。例如,对于同一个 FancyPants 应用程序,我们将有一个“FancyPantsManager”组和一个“FancyPantsUser”组。然后我们设置 SQL Server 2005 登录以映射到服务器上的这些本地组。
我想做的是为用户提供一个登录页面,该页面通过 AD 进行身份验证,然后如果成功,则转到数据库服务器以获取他们的角色(通过调用 xp_logininfo)以存储在用户的会话中。
到目前为止,我通过对 avapi32.dll 文件中的 LogonUser 方法执行 p/Invoke 成功地验证了 Active Directory 的表单身份验证。然后,我获取生成的令牌并生成一个 WindowsIdentity 对象并模拟用户。代码如下所示:
Private Sub loginMain_Authenticate _
(ByVal sender As Object, _
ByVal e As System.Web.UI.WebControls.AuthenticateEventArgs) _
Handles loginMain2.Authenticate
' Assume variables properly declared
IsAuthenticated = LogonUser(UserName, LOGON_DOMAIN, UserPass,
LOGON_TYPE, LOGON_PROVIDER, ResultToken)
If IsAuthenticated
' Setup impersonation for validated user.
WindowsId = New WindowsIdentity(ResultToken)
IdentContext = WindowsId.Impersonate()
' Call stored procedure to retrieve roles using validated user for login.
GetUserRoles(UserName)
End If
End Sub
当我单步调试调试器并输入正确的 ID 和密码时。我通过了身份验证,查看生成的 WindowsIdentity 对象,它指出我的 ID 是“mis1\c07884”,这正是模拟访问 SQL Server 所需要的。但是,当调用 GetRoles 方法时,我收到以下错误消息:
System.Data.SqlClient.SqlException: Could not obtain information
about Windows NT group/user 'c07884', error code 0xffff0002.
在我看来,模拟过程中出现了一些错误。我错过了什么?
【问题讨论】:
【参考方案1】:关注这个问题可能会有所帮助? Active Directory: Retrieving User Information
【讨论】:
不!...我想这不是你想要的,是吗? 关闭,但我需要一个授权令牌,以便我可以连接到数据库,以及为用户的 Web 会话保存部分票证。【参考方案2】:已编辑以删除不相关的内容。
xp_logininfo
。看起来您调用它时将帐户名作为不带域的用户名传递给它。这实际上解释了为什么错误消息说c07884 not found
而不是mis1\c07884 not found
。错误 0xFFFF002 可能是错误 2 ERROR_FILE_NOT_FOUND
。
目前最快的解决方法可能是传递正确的帐户名称:
GetUserRoles(string.Format("0\\1"), LOGON_DOMAIN, UserName));
您应该考虑重写过程以通过不带参数调用x_logininfo
来检索模拟 用户信息以返回当前用户的信息。更好的是,只需 SELECT * FROM
sys.login_token
。
如果您在 ASP 中只需要组成员身份,那么您已经在 WindowsIdentity.Groups 中拥有它。
【讨论】:
我在使用 WindowsIdentity.Groups 时遇到的问题是这些组是数据库服务器的本地组,而不是整个域名。群组是否能够从单个服务器而不是整个域中提取成员资格? 当我调用 GetUserRoles 时,连接字符串被配置为使用 SSPI,我假设这意味着它将采用登录的 WindowsIdentity 的模拟凭据,由于某种原因返回为 c07884 而没有域,有没有办法更新与登录关联的“名称”? 数据库主机是否加入了mis1
域(或者它是否加入了信任mis1
的域)?
好问题。我现在不确定。我想说是的,但需要与我们的运维人员谈谈。以上是关于如何使用 WindowsIdentity 和 SQL Server 集成安全设置表单身份验证的主要内容,如果未能解决你的问题,请参考以下文章
WindowsIdentity winId = (WindowsIdentity)HttpContext.Current.User.Identity;如何使这个演员工作;目前它失败了
C# - 获取 ASPNET WindowsIdentity
如何将 WindowsIdentity 转换为 NetworkCredential?
如何使用 IIS 从 Blazor 服务器获取 WindowsIdentity.RunImpersonated(token, action) 的 HttpContext(或 AccessToken)