Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

.net - Impersonation using ASP.NET Membership Provider

I have a custom membership/roles provider, due to the nature of the project it will require admins to login as users while assisting them with queries.

Now, Its easy to re-log the admin in with the selected membership account, however this means that the admin will effectively be logged out. I'm looking for a way to allow admins to impersonate users yet very easily switch back to there own account at any time.

Any suggestions?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This should be the sort of thing you want.

You can call the ImpersonateValidUser method with the username and password of the domain account you want. And then reverse it on the logout.

You should be able to bend this to work with your custom membership provider.

// Constants for impersonation
private WindowsImpersonationContext impersonationContext;
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;

/// <summary>
/// Changes the account we are running under. 
/// </summary>
/// <param name="username">Username of a local admin account</param>
/// <param name="domain">Domain of the username</param>
/// <param name="password">Password of a local admin account</param>
/// <returns></returns>
private bool ImpersonateValidUser(String username, String domain, String password)
{
    WindowsIdentity tempWindowsIdentity;
    IntPtr token = IntPtr.Zero;
    IntPtr tokenDuplicate = IntPtr.Zero;

    if (RevertToSelf())
    {
        if (LogonUserA(username, domain, password, LOGON32_LOGON_INTERACTIVE,
            LOGON32_PROVIDER_DEFAULT, ref token) != 0)
        {
            if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
            {
                tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                impersonationContext = tempWindowsIdentity.Impersonate();
                if (impersonationContext != null)
                {
                    CloseHandle(token);
                    CloseHandle(tokenDuplicate);
                    return true;
                }
            }
        }
    }
    if (token != IntPtr.Zero)
        CloseHandle(token);
    if (tokenDuplicate != IntPtr.Zero)
        CloseHandle(tokenDuplicate);
    return false;
}

/// <summary>
/// Cancel the impersonation and revent the thread to the
/// default account. Typically DOMAINNETWORK_SERVICE or similar.
/// </summary>
private void UndoImpersonation()
{
    impersonationContext.Undo();
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...