Frage

Ich habe eine ASP.NET-Website, die Formularauthentifizierung und nicht die Windows-Authentifizierung für den Zugriff auf einen ActiveDirectoryMembershipProvider verwenden. Die Website muss Formulare verwenden, weil sie ein entworfenes Eingabeformular anstelle des Browsers Authentifizierung Popup müssen, dass die Windows-Authentifizierung verwendet wird.

Die Seite muss der Benutzer zum Imitieren über Active Directory angemeldet, um benutzerspezifische Dateien zugreifen zu können.

Allerdings ist die WindowsIdentity.GetCurrent() nicht das gleiche wie die HttpContext.Current.User.Identity obwohl meine web.config enthält:

<authentication mode="Forms">
    <forms loginUrl="login.aspx" timeout="480"/>
</authentication>
<identity impersonate="true" />

Ich kann nicht LoginUser() und die WindowsIdentity.Impersonate() benutzen, weil ich als AD Benutzer verkörpern muß ihre spezifische Berechtigungen zu bekommen, und ich weiß nicht, das Kennwort des Benutzers, weil Formulare Pflege der Protokollierung in.

Ist es möglich, vielleicht von dem login.aspx.cs, die System.Web.UI.WebControls.Login.Password zu nehmen, dann die LoginUser() Token später für WindowsIdentity.Impersonate() in einer Sitzungsvariablen speichern? Oder vielleicht eine viel sicherere Methode für den richtigen Weg Impersonating?

Ich bin verwirrt, warum Formularauthentifizierung kann nicht automatisch <identity impersonate="true" />

Ich habe diese http://msdn.microsoft.com/en -US / library / ms998351.aspx aber es nutzt die Windows-Authentifizierung.

War es hilfreich?

Lösung

Imitieren eines Benutzers unter Verwendung von Formularauthentifizierung durchgeführt werden kann. Der folgende Code funktioniert .

Die Visuelle Studio Magazine Artikel von Robert bezeichnet ist eine hervorragende Ressource. Es gibt ein paar Probleme mit dem Beispielcode in dem Artikel, also habe ich einige Arbeits Code unten enthalten.

. Hinweis: Wenn Sie Visual Studio verwenden, stellen Sie sicher, dass es starten " Als Administrator ausführen " Probleme zu vermeiden, mit UAC Identitätswechsel blockiert

// in your login page (hook up to OnAuthenticate event)
protected void LoginControl_Authenticate(object sender, AuthenticateEventArgs e)
{
    int token;
    // replace "YOURDOMAIN" with your actual domain name
    e.Authenticated = LogonUser(LoginUser.UserName,"YOURDOMAIN",LoginUser.Password,8,0,out token);
    if (e.Authenticated) {
        Session.Add("principal", new WindowsPrincipal(new WindowsIdentity(new IntPtr(token))));
    }
}

[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword,
    int dwLogonType, int dwLogonProvider, out int TokenHandle);


// in global.asax.cs
void Application_PreRequestHandlerExecute(object send, EventArgs e)
{
    if (Thread.CurrentPrincipal.Identity.IsAuthenticated == true && HttpContext.Current.Session != null) {
        WindowsPrincipal windowsPrincipal = (WindowsPrincipal)Session["principal"];
        Session["principal"] = (GenericPrincipal)Thread.CurrentPrincipal;
        Thread.CurrentPrincipal = windowsPrincipal;
        HttpContext.Current.User = windowsPrincipal;
        HttpContext.Current.Items["identity"] = ((WindowsIdentity)windowsPrincipal.Identity).Impersonate();
    }
}

// in global.asax.cs
void Application_PostRequestHandlerExecute(object send, EventArgs e)
{
    if (HttpContext.Current.Session != null && Session["principal"] as GenericPrincipal != null) {
        GenericPrincipal genericPrincipal = (GenericPrincipal)Session["principal"];
        Session["principal"] = (WindowsPrincipal)Thread.CurrentPrincipal;
        Thread.CurrentPrincipal = genericPrincipal;
        HttpContext.Current.User = genericPrincipal;
        ((WindowsImpersonationContext)HttpContext.Current.Items["identity"]).Undo();
    }
}

// test that impersonation is working (add this and an Asp:Label to a test page)
protected void Page_Load(object sender, EventArgs e)
{
    try {
        // replace YOURSERVER and YOURDB with your actual server and database names
        string connstring = "data source=YOURSERVER;initial catalog=YOURDB;integrated security=True";
        using (SqlConnection conn = new SqlConnection(connstring)) {
            conn.Open();
            SqlCommand cmd = new SqlCommand("SELECT SUSER_NAME()", conn);
            using (SqlDataReader rdr = cmd.ExecuteReader()) {
                rdr.Read();
                Label1.Text = "SUSER_NAME() = " + rdr.GetString(0);
            }
        }
    }
    catch {
    }
}

Update:

Sie sollten auch Application_EndRequest handhaben, weil Anrufe wie Response.End() werden Application_PostRequestHandlerExecute umgehen.

Ein weiteres Problem ist, dass die Windows kann Müll gesammelt bekommen, so sollten Sie einen neuen Windows und Windows aus dem Anmeldetoken bei jeder Anforderung erstellen.

Update2:

Ich bin mir nicht sicher, warum dies downvoted bekommen, weil es funktioniert. Ich habe die pinvoke Unterschrift und einigen Test-Code hinzugefügt. Auch hier startet Visual Studio mit " Als Administrator ausführen ". Google, wie das tun, wenn Sie nicht wissen, wie.

Andere Tipps

Wenn die Benutzer IE verwenden, dann können Sie schalten Sie die integrierte Sicherheit für die Website und Ihre Benutzer lautlos authentifiziert werden (kein Login-Dialog, keine Login-Seite). Ihre Identitätswechsel wird dann arbeiten. Wenn Sie anderen Browser zielen müssen, dann kann dies nicht funktionieren (der Benutzer wird wahrscheinlich mit einem Login-Dialog angezeigt werden).

Ihre aktuellen Identitätswechsel wird nie funktionieren, weil die Benutzer Anmeldung sind ein anderes Konto als ihre Domäne-Konto zu verwenden. Sie können diese Seite nicht erwarten, dass ein Benutzer verkörpern, die seine Berechtigungsnachweise nicht geliefert hat. Das würde gegen grundlegenden Sicherheitsprinzipien.

Sie finden diese nützlich:

Bearbeiten

Beim Lesen Ihrer Frage näher, ich bin nicht sicher, ob dieser Ansatz mit Ihrem Szenario allerdings funktionieren würde; wenn Sie Login mit Formularauthentifizierung und Imitieren Active Directory Benutzer

Wir haben das gleiche Problem vor kurzem bekam, wollte der Kunde seine Benutzer von AD-Konto anmelden können, und dann muss diese Berechtigungsnachweis verwendet werden Analysis Service sowie alle anderen Datenbanken zuzugreifen. Sie wollten es auf diese Weise, weil sie eine Revisionssystems und alle Zugang eingesetzt werden, müssen durch aktuelle protokollierte Konto erfolgen.

Wir haben versucht, die Formularauthentifizierung und Win32 Logonuser () API für einen Teil Identitätswechsel, es hat funktioniert, aber es fragt auch uns für Kennwort des Benutzers im Klartext. Später wir verwenden die Windows-Authentifizierung entschieden, es uns spart viel Zeit (nicht mehr AD-Authentifizierung, Identitätswechsel manuell). Natürlich gab es auch keine Lust Login-Seite.

Für den Fall der Fälle, und ein bisschen spät, fand ich etwas, das funktioniert für mich und es ist wirklich einfach, aber natürlich ist nur für Testzwecke ...

Setzen Sie einfach ein Cookie mit Ihrem Benutzernamen.

//Login button. You can give whatever input to the form
protected void Login_Click(object sender, EventArgs e)
{
    FormsAuthentication.SetAuthCookie("your_username", createPersistentCookie: true);
    Response.Redirect("~/");
}

Alle Kommentare akzeptiert ...

In Visual Studio installieren NuGet Öffnen Sie Ihre Lösung

Dann in der Paket-Konsole läuft Install-Package 51Degrees.mobi

Es wird dann füge 51Degrees auf Ihre Website. Sie können dann die 51Degrees.mobi.config in Ihren App-Daten bearbeiten, um die Umleitung Abschnitt zu entfernen.

Sie müssen jetzt auf den neuesten Stand Browserfunktionen

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top