1

認証は Windows に設定され、roleManager は AspNetWindowsTokenRoleProvider を使用しています。これはイントラネット アプリケーションです。

アプリケーションのさまざまな役割をテストするために、いくつかの異なるテスト アカウント (Web サーバーに対してローカル) を作成しました。各ユーザーは異なるローカル グループに属し、各グループはアプリケーション内で異なる役割を果たします。ユーザーがアカウントを切り替えるための選択オプションを提供したいと思います。

理想的には、ユーザーが選択できる次の種類のオプションを含むドロップダウン ボックスを Web ページに配置したいと考えています。

  • WindowsUser (現在 Windows にログインしているユーザー、または不明な場合はユーザー名/パスワードのチャレンジ)
  • TestUserForRole1
  • TestUserForRole2
  • TestUserForRole3

これが不可能な場合、次善の策は、ユーザーにユーザー名/パスワードを入力するように促し、サーバーでそれらを認証して、提供された資格情報で新しいセッションを確立することです。私のオプションは何ですか?ありがとう。

4

1 に答える 1

0

私はこれを理解したと思います。私の解決策は、ドロップダウン ボックスを選択して Cookie を設定し、ページを更新することです。イベントでCookie 値を読み取り、必要に応じて要求されたユーザーにApplication_AuthenticateRequest置き換えます。HttpContext.Userコードは次のとおりです。

次のようにユーザーを選択します。

<select id="LoginUser" name="LoginUser" onchange="ChangeLoginUser(this)">
    <option value="NONE">-- Change User --</option>
    <option value="">Windows User</option>
    <option value="UserOne">User One</option>
    <option value="UserTwo">User Two</option>
</select>

ユーザーの選択を JavaScript で処理する ( AppPath リファレンス)

function ChangeLoginUser(sel) {
    var selectedUser = sel.options[sel.selectedIndex].value;
    if (selectedUser == "NONE") return;
    $.cookie("LoginUser", selectedUser, { path: AppPath });
    location.reload(true); //refresh
}

現在ログインしている Windows ユーザーを次の選択でオーバーライドします。

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
    OverrideLoginUser();
}

private void OverrideLoginUser()
{
    HttpCookie authCookie = Context.Request.Cookies["LoginUser"];
    if (authCookie == null || string.IsNullOrWhiteSpace(authCookie.Value))
        return; //regular authentication

    if (User != null && User.Username().Equals(authCookie.Value))
        return; //already set

    Context.User = GetTestUser(authCookie.Value);
}

private WindowsPrincipal GetTestUser(string user)
{
    WindowsPrincipal testuser = null;
    IntPtr hToken;                
    if (WinSec.LogonUser(user, "", "ThePassword", // all users have the same password
        (int)LogonType.LOGON32_LOGON_INTERACTIVE, (int)LogonProvider.LOGON32_PROVIDER_DEFAULT, out hToken))
    {
        testuser = new WindowsPrincipal(new WindowsIdentity(hToken, "WindowsAuthentication"));
        }
        if (hToken != IntPtr.Zero) WinSec.CloseHandle(hToken);
    }

    if (testuser == null)
        throw new Exception("Error getting test user");

    return testuser;
}

ユーザー名() 拡張子

public static string Username(this IPrincipal user)
{
    var name = user.Identity.Name;
    //remove domain name
    name = Regex.Replace(name, ".*\\\\(.*)", "$1", RegexOptions.None);
    return name;
}

UserLogon 関数は、次のクラスで使用可能にする必要があります

/// <summary>
/// http://pinvoke.net/default.aspx/advapi32.LogonUser
/// </summary>
public class WinSec
{
    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool LogonUser(
        string lpszUsername,
        string lpszDomain,
        string lpszPassword,
        int dwLogonType,
        int dwLogonProvider,
        out IntPtr phToken
    );

    [DllImport("advapi32.dll", SetLastError = true)]
    public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, out IntPtr DuplicateTokenHandle);

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool CloseHandle(IntPtr hObject);
}

public enum LogonType
{
    /// <summary>
    /// This logon type is intended for users who will be interactively using the computer, such as a user being logged on  
    /// by a terminal server, remote shell, or similar process.
    /// This logon type has the additional expense of caching logon information for disconnected operations; 
    /// therefore, it is inappropriate for some client/server applications,
    /// such as a mail server.
    /// </summary>
    LOGON32_LOGON_INTERACTIVE = 2,

    /// <summary>
    /// This logon type is intended for high performance servers to authenticate plaintext passwords.

    /// The LogonUser function does not cache credentials for this logon type.
    /// </summary>
    LOGON32_LOGON_NETWORK = 3,

    /// <summary>
    /// This logon type is intended for batch servers, where processes may be executing on behalf of a user without 
    /// their direct intervention. This type is also for higher performance servers that process many plaintext
    /// authentication attempts at a time, such as mail or Web servers. 
    /// The LogonUser function does not cache credentials for this logon type.
    /// </summary>
    LOGON32_LOGON_BATCH = 4,

    /// <summary>
    /// Indicates a service-type logon. The account provided must have the service privilege enabled. 
    /// </summary>
    LOGON32_LOGON_SERVICE = 5,

    /// <summary>
    /// This logon type is for GINA DLLs that log on users who will be interactively using the computer. 
    /// This logon type can generate a unique audit record that shows when the workstation was unlocked. 
    /// </summary>
    LOGON32_LOGON_UNLOCK = 7,

    /// <summary>
    /// This logon type preserves the name and password in the authentication package, which allows the server to make 
    /// connections to other network servers while impersonating the client. A server can accept plaintext credentials 
    /// from a client, call LogonUser, verify that the user can access the system across the network, and still 
    /// communicate with other servers.
    /// NOTE: Windows NT:  This value is not supported. 
    /// </summary>
    LOGON32_LOGON_NETWORK_CLEARTEXT = 8,

    /// <summary>
    /// This logon type allows the caller to clone its current token and specify new credentials for outbound connections.
    /// The new logon session has the same local identifier but uses different credentials for other network connections. 
    /// NOTE: This logon type is supported only by the LOGON32_PROVIDER_WINNT50 logon provider.
    /// NOTE: Windows NT:  This value is not supported. 
    /// </summary>
    LOGON32_LOGON_NEW_CREDENTIALS = 9,
}

public enum LogonProvider
{
    /// <summary>
    /// Use the standard logon provider for the system. 
    /// The default security provider is negotiate, unless you pass NULL for the domain name and the user name 
    /// is not in UPN format. In this case, the default provider is NTLM. 
    /// NOTE: Windows 2000/NT:   The default security provider is NTLM.
    /// </summary>
    LOGON32_PROVIDER_DEFAULT = 0,
    LOGON32_PROVIDER_WINNT35 = 1,
    LOGON32_PROVIDER_WINNT40 = 2,
    LOGON32_PROVIDER_WINNT50 = 3
}

public enum SecurityImpersonationLevel
{
    /// <summary>
    /// The server process cannot obtain identification information about the client, 
    /// and it cannot impersonate the client. It is defined with no value given, and thus, 
    /// by ANSI C rules, defaults to a value of zero. 
    /// </summary>
    SecurityAnonymous = 0,

    /// <summary>
    /// The server process can obtain information about the client, such as security identifiers and privileges, 
    /// but it cannot impersonate the client. This is useful for servers that export their own objects, 
    /// for example, database products that export tables and views. 
    /// Using the retrieved client-security information, the server can make access-validation decisions without 
    /// being able to use other services that are using the client's security context. 
    /// </summary>
    SecurityIdentification = 1,

    /// <summary>
    /// The server process can impersonate the client's security context on its local system. 
    /// The server cannot impersonate the client on remote systems. 
    /// </summary>
    SecurityImpersonation = 2,

    /// <summary>
    /// The server process can impersonate the client's security context on remote systems. 
    /// NOTE: Windows NT:  This impersonation level is not supported.
    /// </summary>
    SecurityDelegation = 3,
}
于 2012-07-19T18:18:16.027 に答える