DevTrain Startseite Advanced Developers Conference vom 14.-15. Februar 2011  
  
  
SUCHEN:  
ARTIKEL ONLINE: 525   

Kategorien
.NET
Datenbanken
Web
XML

Allgemein
Camp
Foren
Events
Persönliche Einstellungen
Registrieren
Prämien Shop
Kontakt
Impressum
Über DevTrain

Autoren


   Autor: Tobi Ulm Artikel Drucken
        
Identitätswechsel (Impersonation) in ASP.NET

Impersonierung ermöglicht es den Quellcode unter einem anderem Benutzerkontext ausführen zu lassen.

Dabei stehen zwei Möglichkeiten zur Verfügung:

1. Identitätswechsel mittels Internet Information Server und der Web.Config

Es besteht in der Web.Config die Möglichkeit das <identity> Element einzutragen. Dadurch wird durch den IIS ein Identitätswechsel des Prozesses durchgeführt.

Sie können entweder wenn die Web Anwendung eine Intranetanwendung ist, die Authentifizierung und damit das Benutzerkonto durch den IIS durchreichen lassen, oder sie können ein bestimmtes Benutzerkonto, welches natürlich auf dem Rechner angelegt sein muss, angeben.

Beispiel für den Identitätswechsel mit Windows Authentifizierung innerhalb eines Intranets:

<identity impersonate="true" />

Zu beachten ist das das Web oder das virtuelle Verzeichnis mit Windows Authentifizierung ausgestattet ist.

Beispiel für den Identitätswechsel mit einem speziell angelegten Benutzerkontos:

<identity impersonate="true" userName="IrgendeinBenutzerkonto" password="DasPasswort" />

Bitte beachten Sie das die Benutzerinformationen als Klartext hinterlegt sind und somit für jedermann der Zugriff auf den Computer hat auslesbar sind. Aus diesem Grund möchte ich auf einen Artikel von mir verweisen in dem ich das ASPNET_SETREG Tool vorgestellt habe und in dem Beschrieben wird wie über die DPAPI mit diesem Tool die Benutzerinformationen verschlüsselt werden können.

http://www.devtrain.de/news.aspx?artnr=915

Zwischenbilanz: Durch die Web.Config ist es sehr einfach einen Identitätswechsel des ASP.NET Prozesses zu ermöglichen. Natürlich läuft damit die Anwendung immer mit den Benutzerkonten so wie es in der Web.Config eingestellt wurde. Was aber, wenn man nur bestimmte Teile des Quellcodes unter einem anderem Benutzerkonto laufen lassen will?

2. Identitätswechsel durch Code

Hier hilft nur Code. Als erstes muss erwähnt werden dass es im .NET Framework bis jetzt keine geeigneten Klassen gibt mit denen man einem Benutzer es ermöglichen kann sich an einer anderen Domäne anzumelden. Es muss auf Windows API Funktionen der Bibliothek advapi32.dll, zurückgegriffen werden, in der sich die Anmeldefunktion LogonUser befindet.. Es folgt nun eine Beispiel Klasse welche benutzt werden kann um solch einen Identitätswechsel im Code durchzuführen. Anmerkung: Es muss natürlich Ermöglicht werden die Benutzerinformationen auszulesen.

using System;

using System.Web;

using System.Web.Security;

using System.Security.Principal;

using System.Runtime.InteropServices;

namespace tu.Web.Security.Impersonation{

public class ImpersonateUser : IDisposable{

#region "datamember"

protected const int LOGON32_LOGON_INTERACTIVE = 2;

protected const int LOGON32_PROVIDER_DEFAULT = 0;

private WindowsImpersonationContext m_impersonationContext;

#endregion"

#region "properties"

public WindowsImpersonationContext ImpersonationContext{

get{

return this.m_impersonationContext;

}

}

#endregion

#region "ctor"

public ImpersonateUser(string username, string domain, string pwd){

if(this.ImpersonateValidUser(username, domain, pwd)) {

}

else {

throw new ApplicationException("Error during impersonating the current user.");

}

}

#endregion

 

#region "dtor"

public virtual void Dispose(){

this.UndoImpersonation();

}

#endregion

 

#region "Declaration of ApiFunctions"

[DllImport("advapi32.dll", CharSet=CharSet.Auto)]

public static extern int LogonUser(String lpszUserName,

String lpszDomain,

String lpszPassword,

int dwLogonType,

int dwLogonProvider,

ref IntPtr phToken);

[DllImport("advapi32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto, SetLastError=true)]

public extern static int DuplicateToken(IntPtr hToken,

int impersonationLevel,

ref IntPtr hNewToken);

 

#endregion

 

#region "helper functions"

private bool ImpersonateValidUser(string userName, string domain, string password) {

WindowsIdentity tempWindowsIdentity;

IntPtr token = IntPtr.Zero;

IntPtr tokenDuplicate = IntPtr.Zero;

if(LogonUser(userName, domain, password, LOGON32_LOGON_INTERACTIVE,

LOGON32_PROVIDER_DEFAULT, ref token) != 0) {

if(DuplicateToken(token, 2, ref tokenDuplicate) != 0) {

tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);

this.m_impersonationContext = tempWindowsIdentity.Impersonate();

if (this.m_impersonationContext != null){

return true;

}

else{

return false;

}

}

else{

return false;

}

}

else{

return false;

}

}

public void UndoImpersonation() {

this.m_impersonationContext.Undo();

}

#endregion

}

}

Kompilieren Sie die Klassenbibliothek und erzeugen Sie eine neue ASP.NET Web Anwendung

Die WebForm:

<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="WebAppImpersonation.WebForm1" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >

<HTML>

<HEAD>

<title>WebForm1</title>

<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">

<meta name="CODE_LANGUAGE" Content="C#">

<meta name="vs_defaultClientScript" content="JavaScript">

<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">

</HEAD>

<body>

<form id="Form1" method="post" runat="server">

<TABLE id="Table1" cellSpacing="1" cellPadding="1" width="300" border="1">

<TR>

<TD>

<asp:Label id="Label1" runat="server">LogIn</asp:Label></TD>

<TD>

<asp:TextBox id="Name" runat="server"></asp:TextBox></TD>

<TD></TD>

</TR>

<TR>

<TD>

<asp:Label id="Label2" runat="server">PWD</asp:Label></TD>

<TD>

<asp:TextBox id="Pwd" runat="server" TextMode="Password"></asp:TextBox></TD>

<TD></TD>

</TR>

<TR>

<TD>

<asp:Label id="Label3" runat="server">Domain</asp:Label></TD>

<TD>

<asp:TextBox id="Domain" runat="server"></asp:TextBox></TD>

<TD>

<asp:Button id="cmdImpersonate" runat="server" Text="Write with Impersonate"></asp:Button>

<asp:Button id="Button1" runat="server" Text="Write with aspnet account"></asp:Button></TD>

</TR>

</TABLE>

<asp:Label id="Message" runat="server"></asp:Label>

</form>

</body>

</HTML>

Setzen Sie einen Verweis auf vorher erzeugte Klassenbibliothek

Fügen Sie folgenden Quellcode in den Codebehind der WebForm

using System;

using System.Collections;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Web;

using System.Web.SessionState;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.HtmlControls;

using System.Security.Principal;

using tu.Web.Security.Impersonation;

using System.IO;

namespace WebAppImpersonation{

public class WebForm1 : System.Web.UI.Page{

protected System.Web.UI.WebControls.Label Label1;

protected System.Web.UI.WebControls.Label Label2;

protected System.Web.UI.WebControls.Label Label3;

protected System.Web.UI.WebControls.TextBox Name;

protected System.Web.UI.WebControls.TextBox Pwd;

protected System.Web.UI.WebControls.TextBox Domain;

protected System.Web.UI.WebControls.Button cmdImpersonate;

protected System.Web.UI.WebControls.Label Message;

protected System.Web.UI.WebControls.Button Button1;

private WindowsImpersonationContext theNewUser = null;

private void Page_Load(object sender, System.EventArgs e){

}

#region Vom Web Form-Designer generierter Code

override protected void OnInit(EventArgs e)

{

InitializeComponent();

base.OnInit(e);

}

private void InitializeComponent()

{

this.cmdImpersonate.Click += new System.EventHandler(this.cmdImpersonate_Click);

this.Button1.Click += new System.EventHandler(this.Button1_Click);

this.Load += new System.EventHandler(this.Page_Load);

}

#endregion

private void cmdImpersonate_Click(object sender, System.EventArgs e) {

WindowsPrincipal myPrincipal = (WindowsPrincipal)System.Threading.Thread.CurrentPrincipal;

ImpersonateUser iuser = new ImpersonateUser(this.Name.Text, this.Domain.Text, this.Pwd.Text);

this.theNewUser = iuser.ImpersonationContext;

myPrincipal = (WindowsPrincipal)System.Threading.Thread.CurrentPrincipal;

System.IO.StreamWriter swr = null;

try{

swr = new StreamWriter(@"Laufwerk\Ordner\impers.txt");

swr.Write(DateTime.Now.ToString("D"));

}

catch( Exception eXP ){

Response.Write(eXP.ToString());

}

finally{

if ( swr != null ){

swr.Close();

}

}

}

private void Button1_Click(object sender, System.EventArgs e) {

try{

System.IO.StreamWriter swr = new StreamWriter(@"Laufwerk\Ordner\impers.txt");

swr.Write(DateTime.Now.ToString("D"));

}

catch( Exception eXP ){

Response.Write(eXP.ToString());

}

}

}

}

Erzeugen Sie einen neuen Ordner, fügen Sie das ASPNET Benutzerkonto hinzu und verweigern Sie den Vollzugriff.

Starten Sie die Anwendung.


DevTrain Camp - Schneller zum .NET 3.5 Developer
 
Verwandte Artikel      Verlinkte Dokumente
    Keine verknüpften Dokumente
    Keine Links vorhanden

  Erfasst am: 30.09.2004
  Gültig bis: 29.12.2004
5 Ratings
Bewertung: 84,0%
schlecht    sehr gut  

 
© Copyright 2007 ppedv AG