简体   繁体   English

ASP.NET用户模拟

[英]ASP.NET User Impersonation

I have an ASP.NET MVC application that accesses an database to retrieve some data and updates data on another database when the form is submitted. 我有一个ASP.NET MVC应用程序访问数据库以检索一些数据并在提交表单时更新另一个数据库上的数据。 Both databases and IIS are on different servers and the users will be accessing this remotely, but everything is within out intranet. 数据库和IIS都位于不同的服务器上,用户将远程访问这些服务器,但所有内容都在内部网中。 Access to the databases are granted to the users via groups. 通过组向用户授予对数据库的访问权限。

This means i need to use the user's credentials (the person browsing to the asp net application) to access both databases and i am having a lot of trouble getting this to work. 这意味着我需要使用用户的凭据(浏览到asp网络应用程序的人)来访问这两个数据库,我在使用它时遇到了很多麻烦。 Here's what i've been trying: 这是我一直在尝试的:

After deploying the application and opening it remotely, it opens but the method that accesses the database returns Login failed for domain/servername. 部署应用程序并远程打开它后,它会打开,但访问数据库的方法会返回domain / servername的登录失败。

  1. Enabled impersonation: "An ASP.NET setting has been detected that does not apply in Integrated managed pipeline mode." 启用模拟:“检测到的ASP.NET设置不适用于集成管理管道模式。”
  2. validateIntegratedModeConfiguration="false" - > DirectoryServicesCOMException (0x80072020): An operations error occurred. validateIntegratedModeConfiguration =“false” - > DirectoryServicesCOMException(0x80072020):发生操作错误。
  3. Disabled impersonation and tried to add code to impersonate only on the section of code i access the DB using: 禁用模拟并尝试添加代码以仅模拟我使用以下代码访问数据库的代码部分:

     ((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate(); 

    which resulted in Login failed for NT AUTHORITY/ANONYMOUS LOGON 导致NT AUTHORITY / ANONYMOUS LOGON登录失败

My connection string is 我的连接字符串是

    "Data Source=" + SERVER + ";Initial Catalog=" + DB + ";Integrated Security=True;Connection Timeout=30;Trusted_Connection=true"

Note: he application works perfectly when debugging on visual studio and accessing it locally on the server i deployed it at (with impersonation enabled). 注意:在Visual Studio上进行调试并在我部署它的服务器上本地访问它时,应用程序可以正常工作(启用模拟)。 Also, we use smartcard login and i cannot ask credentials to the user. 此外,我们使用智能卡登录,我不能向用户询问凭据。 I cannot use another ID on behalf of the user due to the security models of our servers. 由于我们服务器的安全模型,我无法代表用户使用其他ID。

I suspect your web app is not authenticating your users, otherwise you wouldn't get that Login failed for NT AUTHORITY/ANONYMOUS LOGON message. 我怀疑您的网络应用程序未对您的用户进行身份验证,否则您将无法获得Login failed for NT AUTHORITY/ANONYMOUS LOGON消息的Login failed for NT AUTHORITY/ANONYMOUS LOGON

Check your IIS web site settings and ensure anonymous authentication is disabled. 检查IIS网站设置并确保禁用匿名身份验证。

What you are doing/asked to do is typically frowned upon. 您正在做/被要求做的事情通常不受欢迎。 When you have Integrated Security=True set in your connection string, the SID/user access the connection is defined by the application pool. 在连接字符串中设置Integrated Security=True ,SID / user访问连接由应用程序池定义。 This allows SQL Connection Pooling to work very efficiently. 这允许SQL连接池非常有效地工作。

When you try to access the SQL server using Integrated Security with Pass-through authentication or impersonation, you basically lose all value from the connection pool (because now each connection has to be created with the user credentials and cannot be shared across requests). 当您尝试使用带有传递身份验证或模拟的集成安全性访问SQL Server时,您基本上会丢失连接池中的所有值(因为现在每个连接都必须使用用户凭据创建,并且不能跨请求共享)。

Normally when I come across this situation, I create a user, grant db access and use that user with the application pool. 通常,当我遇到这种情况时,我创建一个用户,授予db访问权限并将该用户与应用程序池一起使用。 When a user authenticates on the website (windows or basic auth) I use Active Directory Services or LDAP to verify the user has access to the application. 当用户在网站上进行身份验证(Windows或基本身份验证)时,我使用Active Directory服务或LDAP来验证用户是否有权访问该应用程序。

I had a similar problem with impersonation not working in MVC. 我有一个类似的问题,冒充不在MVC工作。

I had to code out the impersonation using win32 calls to log in a specific user. 我不得不使用win32调用来编写模拟以登录特定用户。 Then I found this didn't play well with SQLClient and had to improve it further. 然后我发现这与SQLClient不能很好地合作,并且必须进一步改进它。

Its not quite what you want but here's the code I'm currently using. 它不是你想要的,但这里是我正在使用的代码。 compiled from various internet sources 从各种互联网资源编译

public class Impersonator
{
    public WindowsImpersonationContext Impersonate(string username, string domain, string password)
    {
        WindowsIdentity tempWindowsIdentity;
        const int LOGON32_PROVIDER_DEFAULT = 0;
        //This parameter causes LogonUser to create a primary token. 
        const int LOGON32_LOGON_INTERACTIVE = 2;
        SafeTokenHandle token;
        IntPtr tokenDuplicate = IntPtr.Zero;

        if (NativeMethods.RevertToSelf())
        {
            // Call LogonUser to obtain a handle to an access token. 
            bool returnValue = NativeMethods.LogonUser(
                username,
                domain,
                password,
                LOGON32_LOGON_INTERACTIVE,
                LOGON32_PROVIDER_DEFAULT,
                out token);

            if (returnValue)
            {
                if (NativeMethods.DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                {
                    tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                    NativeMethods.CloseHandle(tokenDuplicate);
                    return tempWindowsIdentity.Impersonate();
                }
                else
                {
                    throw new Exception("unable to login as specifed user - duplicate ");
                }
            }
            else
            {
                throw new Exception("unable to login as specifed user ");
            }
        }
        else
        {
            throw new Exception("could not revert to self ");
        }
        using (WindowsIdentity id = new WindowsIdentity(token.DangerousGetHandle()))
        {
            return id.Impersonate();
        }
    }
}
internal static class NativeMethods
{
    [DllImport("kernel32.dll")]
    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
    [SuppressUnmanagedCodeSecurity]
    [return: MarshalAs(UnmanagedType.Bool)]
    internal static extern bool CloseHandle(IntPtr handle);

    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    internal static extern bool LogonUser(
        String lpszUsername, 
        String lpszDomain, 
        String lpszPassword,
        int dwLogonType, 
        int dwLogonProvider, 
        out SafeTokenHandle phToken);

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern int DuplicateToken(
        SafeTokenHandle hToken,
        int impersonationLevel,
        ref IntPtr hNewToken);

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool RevertToSelf();
}

public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
{
    private SafeTokenHandle()
        : base(true)
    {
    }

    protected override bool ReleaseHandle()
    {
        return NativeMethods.CloseHandle(handle);
    }
}

The reason that is being caused it is the Server tries to access the Database and the Server is not trusted by the Database, so it could not resolve the credentials. 导致它的原因是服务器尝试访问数据库并且数据库不信任服务器,因此无法解析凭据。

You could use an explicit id at the Application Pool and setting the Impersonate Disabled. 您可以在应用程序池中使用显式ID并将Impersonate设置为已禁用。 The IIS will run on behalf the ID. IIS将代表ID运行。 Make sure the ID have the Database Access. 确保ID具有数据库访问权限。 This will be the more secure solution. 这将是更安全的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM