Vorgehensweise: Erstellen eines benutzerdefinierten Sicherheitstokenauthentifizierers

In diesem Thema wird beschrieben, wie Sie einen benutzerdefinierten Sicherheitstokenauthentifizierer erstellen und in einen benutzerdefinierten Sicherheitstoken-Manager integrieren.Ein Sicherheitstokenauthentifizierer überprüft den Inhalt eines Sicherheitstokens, das mit einer eingehenden Nachricht bereitgestellt wird.Bei erfolgreicher Validierung gibt der Authentifizierer eine Sammlung von IAuthorizationPolicy-Instanzen zurück, die nach der Auswertung einen Satz von Ansprüchen zurückgeben.

Zur Verwendung eines benutzerdefinierten Sicherheitstokenauthentifizierers in Windows Communication Foundation (WCF) müssen Sie zunächst benutzerdefinierte Anmeldeinformationen und Sicherheitstoken-Manager-Implementierungen erstellen.Weitere Informationen zum Erstellen von benutzerdefinierten Anmeldeinformationen und Sicherheitstoken-Managern finden Sie unter Exemplarische Vorgehensweise: Erstellen von benutzerdefinierten Client- und Dienstanmeldeinformationen.Weitere Informationen über Anmeldeinformationen, Sicherheitstoken-Manager sowie Anbieter- und Authentifiziererklassen finden Sie unter Security Architecture.

Prozeduren

So erstellen Sie einen benutzerdefinierten Sicherheitstokenauthentifizierer

  1. Definieren Sie eine neue Klasse, die von der SecurityTokenAuthenticator-Klasse abgeleitet wird.

  2. Überschreiben Sie die CanValidateTokenCore-Methode.Die Methode gibt true oder false zurück, je nachdem, ob der benutzerdefinierte Authentifizierer den eingehenden Tokentyp auswerten kann oder nicht.

  3. Überschreiben Sie die ValidateTokenCore-Methode.Diese Methode muss den Tokeninhalt entsprechend überprüfen.Wenn das Token den Validierungsschritt übergibt, gibt es eine Auflistung von IAuthorizationPolicy-Instanzen zurück.Im folgenden Beispiel wird eine benutzerdefinierte Autorisierungsrichtlinienimplementierung, die in der nächsten Prozedur erstellt wird, verwendet.

    internal class MySecurityTokenAuthenticator : SecurityTokenAuthenticator
    {
        protected override bool CanValidateTokenCore(SecurityToken token)
        {
            // Check that the incoming token is a username token type that  
            // can be validated by this implementation.
            return (token is UserNameSecurityToken);
        }
    
        protected override ReadOnlyCollection<IAuthorizationPolicy> 
            ValidateTokenCore(SecurityToken token)
        {
            UserNameSecurityToken userNameToken = token as UserNameSecurityToken;
    
            // Validate the information contained in the username token. For demonstration 
            // purposes, this code just checks that the user name matches the password.
            if (userNameToken.UserName != userNameToken.Password)
            {
                throw new SecurityTokenValidationException("Invalid user name or password");
            }
    
            // Create just one Claim instance for the username token - the name of the user.
            DefaultClaimSet userNameClaimSet = new DefaultClaimSet(
                ClaimSet.System, 
                new Claim(ClaimTypes.Name, userNameToken.UserName, Rights.PossessProperty));
            List<IAuthorizationPolicy> policies = new List<IAuthorizationPolicy>(1);
            policies.Add(new MyAuthorizationPolicy(userNameClaimSet));
            return policies.AsReadOnly();
        }
    }
    
    Friend Class MySecurityTokenAuthenticator
        Inherits SecurityTokenAuthenticator
    
        Protected Overrides Function CanValidateTokenCore(ByVal token As SecurityToken) As Boolean
            ' Check that the incoming token is a username token type that  
            ' can be validated by this implementation.
            Return (TypeOf token Is UserNameSecurityToken)
        End Function
    
        Protected Overrides Function ValidateTokenCore(ByVal token As SecurityToken) As ReadOnlyCollection(Of IAuthorizationPolicy)
    
            Dim userNameToken = TryCast(token, UserNameSecurityToken)
    
            ' Validate the information contained in the username token. For demonstration 
            ' purposes, this code just checks that the user name matches the password.
            If userNameToken.UserName <> userNameToken.Password Then
                Throw New SecurityTokenValidationException("Invalid user name or password")
            End If
    
            ' Create just one Claim instance for the username token - the name of the user.
            Dim userNameClaimSet As New DefaultClaimSet(ClaimSet.System, _
                                                        New Claim(ClaimTypes.Name, _
                                                        userNameToken.UserName, _
                                                        Rights.PossessProperty))
            Dim policies As New List(Of IAuthorizationPolicy)(1)
            policies.Add(New MyAuthorizationPolicy(userNameClaimSet))
            Return policies.AsReadOnly()
        End Function
    
    End Class
    

Der vorherige Code gibt eine Sammlung von Autorisierungsrichtlinien in der CanValidateToken(SecurityToken)-Methode zurück.WCF stellt keine öffentliche Implementierung dieser Schnittstelle zur Verfügung.Die folgende Prozedur zeigt, wie Sie diese Schritte Ihren eigenen Anforderungen entsprechend ausführen.

So erstellen Sie eine benutzerdefinierte Autorisierungsrichtlinie

  1. Definieren Sie eine neue Klasse, die die IAuthorizationPolicy-Schnittstelle implementiert.

  2. Implementieren Sie die schreibgeschützte Id-Eigenschaft.Eine Möglichkeit, diese Eigenschaft zu implementieren, besteht darin, eine GUID (Globally Unique Identifier) im Klassenkonstruktor zu generieren und jedes Mal zurückzugeben, wenn der Wert für diese Eigenschaft angefordert wird.

  3. Implementieren Sie die schreibgeschützte Issuer-Eigenschaft.Diese Eigenschaft muss einen Aussteller der Sätze von Ansprüchen zurückgeben, die aus dem Token abgerufen werden.Dieser Aussteller sollte dem Aussteller des Tokens oder einer Autorität entsprechen, die für die Überprüfung der Tokeninhalte zuständig ist.Im folgenden Beispiel wird der Ausstelleranspruch, der von dem in der vorherigen Prozedur erstellten benutzerdefinierten Sicherheitstokenauthentifizierer an diese Klasse übergeben wird, verwendet.Der benutzerdefinierte Sicherheitstokenauthentifizierer nutzt den vom System bereitgestellten Satz von Ansprüchen (der von der System-Eigenschaft zurückgegeben wird), um den Aussteller des Benutzernamentokens darzustellen.

  4. Implementieren Sie die Evaluate-Methode.Diese Methode füllt eine Instanz der EvaluationContext-Klasse (die als Argument weitergegeben wurde) mit Ansprüchen auf, die auf dem eingehenden Sicherheitstokeninhalt basieren.Die Methode gibt true zurück, wenn der Vorgang mit der Evaluierung vorgenommen wird.In Fällen, in denen die Implementierung vom Vorhandensein anderer Autorisierungsrichtlinien abhängt, die zusätzliche Informationen zum Evaluierungskontext bieten, kann diese Methode false zurückgeben, wenn die erforderlichen Informationen noch nicht im Evaluierungskontext vorhanden sind.In diesem Fall ruft WCF die Methode erneut auf, nachdem alle anderen Autorisierungsrichtlinien, die für die eingehende Nachricht generiert wurden, überprüft wurden und festgestellt wurde, ob mindestens eine der Autorisierungsrichtlinien den Evaluierungskontext modifiziert hat.

    internal class MyServiceCredentialsSecurityTokenManager : 
        ServiceCredentialsSecurityTokenManager
    {
        ServiceCredentials credentials;
        public MyServiceCredentialsSecurityTokenManager(ServiceCredentials credentials)
            : base(credentials)
        {
            this.credentials = credentials;
        }
    
        public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator
            (SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver)
        {
            // Return your implementation of the SecurityTokenProvider based on the 
            // tokenRequirement argument.
            SecurityTokenAuthenticator result;
            if (tokenRequirement.TokenType == SecurityTokenTypes.UserName)
            {
                MessageDirection direction = tokenRequirement.GetProperty<MessageDirection>
                    (ServiceModelSecurityTokenRequirement.MessageDirectionProperty);
                if (direction == MessageDirection.Input)
                {
                    outOfBandTokenResolver = null;
                    result = new MySecurityTokenAuthenticator();
                }
                else
                {
                    result = base.CreateSecurityTokenAuthenticator(tokenRequirement, out outOfBandTokenResolver);
                }
            }
            else
            {
                result = base.CreateSecurityTokenAuthenticator(tokenRequirement, out outOfBandTokenResolver);
            }
    
            return result;
        }
    }
    
    Friend Class MyServiceCredentialsSecurityTokenManager
        Inherits ServiceCredentialsSecurityTokenManager
    
        Private credentials As ServiceCredentials
    
        Public Sub New(ByVal credentials As ServiceCredentials)
            MyBase.New(credentials)
            Me.credentials = credentials
        End Sub
    
        Public Overrides Function CreateSecurityTokenAuthenticator(ByVal tokenRequirement As SecurityTokenRequirement, _
                                                                   <System.Runtime.InteropServices.Out()> _
                                                                   ByRef outOfBandTokenResolver _
                                                                   As SecurityTokenResolver) As SecurityTokenAuthenticator
            ' Return your implementation of the SecurityTokenProvider based on the 
            ' tokenRequirement argument.
            Dim result As SecurityTokenAuthenticator
            If tokenRequirement.TokenType = SecurityTokenTypes.UserName Then
                Dim direction = tokenRequirement.GetProperty(Of MessageDirection)(ServiceModelSecurityTokenRequirement.MessageDirectionProperty)
                If direction = MessageDirection.Input Then
                    outOfBandTokenResolver = Nothing
                    result = New MySecurityTokenAuthenticator()
                Else
                    result = MyBase.CreateSecurityTokenAuthenticator(tokenRequirement, _
                                                                     outOfBandTokenResolver)
                End If
            Else
                result = MyBase.CreateSecurityTokenAuthenticator(tokenRequirement, _
                                                                 outOfBandTokenResolver)
            End If
    
            Return result
        End Function
    
    End Class
    

Exemplarische Vorgehensweise: Erstellen von benutzerdefinierten Client- und Dienstanmeldeinformationen beschreibt, wie benutzerdefinierte Anmeldeinformationen und ein benutzerdefinierter Sicherheitstoken-Manager erstellt werden.Zur Verwendung des hier erstellten benutzerdefinierten Sicherheitstokenauthentifizierers wird eine Implementierung des Sicherheitstoken-Managers so geändert, dass der benutzerdefinierte Authentifizierer von der CreateSecurityTokenAuthenticator-Methode zurückgegeben wird.Die Methode gibt einen Authentifizierer zurück, wenn eine entsprechende Sicherheitstokenanforderung übergeben wird.

So integrieren Sie einen benutzerdefinierten Sicherheitstokenauthentifizierer mit einem benutzerdefinierten Sicherheitstoken-Manager

  1. Überschreiben Sie die CreateSecurityTokenAuthenticator-Methode in der benutzerdefinierten Sicherheitstoken-Manager-Implementierung.

  2. Fügen Sie Logik zur Methode hinzu, um diese zu befähigen, Ihren benutzerdefinierten Sicherheitstokenauthentifizierer basierend auf dem SecurityTokenRequirement-Parameter zurückzugeben.Im folgenden Beispiel wird ein benutzerdefinierter Sicherheitstokenauthentifizierer zurückgegeben, wenn der Tokentyp der Tokenanforderungen ein Benutzername ist (der von der UserName-Eigenschaft dargestellt wird) und die Nachrichtenrichtung, für die der Sicherheitstokenauthentifizierer angefordert wird, eingegeben wird (dargestellt durch das MessageDirection-Feld).

    internal class MyAuthorizationPolicy : IAuthorizationPolicy
    {
        string id;
        ClaimSet tokenClaims;
        ClaimSet issuer;
    
        public MyAuthorizationPolicy(ClaimSet tokenClaims)
        {
            if (tokenClaims == null)
            {
                throw new ArgumentNullException("tokenClaims");
            }
            this.issuer = tokenClaims.Issuer;
            this.tokenClaims = tokenClaims;
            this.id = Guid.NewGuid().ToString();
        }
    
        public ClaimSet Issuer
        {
            get { return issuer; }
        }
    
        public string Id
        {
            get { return id; }
        }
    
        public bool Evaluate(EvaluationContext evaluationContext, ref object state)
        {
            // Add the token claim set to the evaluation context.
            evaluationContext.AddClaimSet(this, tokenClaims);
    
            // Return true if the policy evaluation is finished.
            return true;
        }
    }
    
    Friend Class MyAuthorizationPolicy
        Implements IAuthorizationPolicy
    
        Private _id As String
        Private _tokenClaims As ClaimSet
        Private _issuer As ClaimSet
    
        Public Sub New(ByVal tokenClaims As ClaimSet)
            If _tokenClaims Is Nothing Then
                Throw New ArgumentNullException("tokenClaims")
            End If
            Me._issuer = tokenClaims.Issuer
            Me._tokenClaims = tokenClaims
            Me._id = Guid.NewGuid().ToString()
        End Sub
    
        Public ReadOnly Property Issuer() As ClaimSet Implements IAuthorizationPolicy.Issuer
            Get
                Return _issuer
            End Get
        End Property
    
        Public ReadOnly Property Id() As String Implements System.IdentityModel.Policy.IAuthorizationComponent.Id
            Get
                Return _id
            End Get
        End Property
    
        Public Function Evaluate(ByVal evaluationContext As EvaluationContext, _
                                 ByRef state As Object) As Boolean Implements IAuthorizationPolicy.Evaluate
    
            ' Add the token claim set to the evaluation context.
            evaluationContext.AddClaimSet(Me, _tokenClaims)
            ' Return true if the policy evaluation is finished.
            Return True
        End Function
    
    End Class
    

Siehe auch

SecurityTokenAuthenticator
SecurityTokenRequirement
SecurityTokenManager
UserNameSecurityToken
Exemplarische Vorgehensweise: Erstellen von benutzerdefinierten Client- und Dienstanmeldeinformationen
Vorgehensweise: Erstellen eines benutzerdefinierten Sicherheitstokenanbieters
Security Architecture