Udostępnij za pośrednictwem


Instrukcje: tworzenie niestandardowego wystawcy uwierzytelniania tokenu zabezpieczającego

W tym temacie przedstawiono sposób tworzenia niestandardowego wystawcy uwierzytelniającego tokenu zabezpieczającego i sposobu jego integracji z niestandardowym menedżerem tokenów zabezpieczających. Wystawca uwierzytelnienia tokenu zabezpieczającego weryfikuje zawartość tokenu zabezpieczającego dostarczonego z komunikatem przychodzącym. Jeśli walidacja zakończy się pomyślnie, wystawca uwierzytelnienia zwróci kolekcję IAuthorizationPolicy wystąpień, które po ocenie zwracają zestaw oświadczeń.

Aby użyć niestandardowego wystawcy uwierzytelniania tokenów zabezpieczających w programie Windows Communication Foundation (WCF), należy najpierw utworzyć niestandardowe poświadczenia i implementacje menedżera tokenów zabezpieczających. Aby uzyskać więcej informacji na temat tworzenia poświadczeń niestandardowych i menedżera tokenów zabezpieczających, zobacz Przewodnik: tworzenie niestandardowych poświadczeń klienta i usługi.

z konkretnym obiektem

Aby utworzyć niestandardowy wystawca uwierzytelniania tokenu zabezpieczającego

  1. Zdefiniuj nową klasę pochodzącą SecurityTokenAuthenticator z klasy .

  2. Zastąpij metodę CanValidateTokenCore . Metoda zwraca true lub false w zależności od tego, czy niestandardowy wystawca uwierzytelniający może zweryfikować typ tokenu przychodzącego, czy nie.

  3. Zastąpij metodę ValidateTokenCore . Ta metoda musi odpowiednio zweryfikować zawartość tokenu. Jeśli token przejdzie krok weryfikacji, zwraca kolekcję IAuthorizationPolicy wystąpień. W poniższym przykładzie użyto niestandardowej implementacji zasad autoryzacji, która zostanie utworzona w następnej procedurze.

    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
    

Poprzedni kod zwraca kolekcję zasad autoryzacji w metodzie CanValidateToken(SecurityToken) . Program WCF nie zapewnia publicznej implementacji tego interfejsu. Poniższa procedura pokazuje, jak to zrobić dla własnych wymagań.

Aby utworzyć niestandardowe zasady autoryzacji

  1. Zdefiniuj nową klasę implementowania interfejsu IAuthorizationPolicy .

  2. Zaimplementuj Id właściwość tylko do odczytu. Jednym ze sposobów zaimplementowania tej właściwości jest wygenerowanie globalnie unikatowego identyfikatora (GUID) w konstruktorze klasy i zwrócenie jej za każdym razem, gdy żądana jest wartość tej właściwości.

  3. Zaimplementuj Issuer właściwość tylko do odczytu. Ta właściwość musi zwrócić wystawcę zestawów oświadczeń uzyskanych z tokenu. Ten wystawca powinien odpowiadać wystawcy tokenu lub urzędu odpowiedzialnego za weryfikowanie zawartości tokenu. W poniższym przykładzie użyto oświadczenia wystawcy przekazanego do tej klasy z niestandardowego wystawcy uwierzytelniającego tokenu zabezpieczającego utworzonego w poprzedniej procedurze. Niestandardowy wystawca uwierzytelnienia tokenu zabezpieczającego używa zestawu oświadczeń dostarczonych przez system (zwracanego przez System właściwość) do reprezentowania wystawcy tokenu nazwy użytkownika.

  4. Zaimplementuj metodę Evaluate . Ta metoda wypełnia wystąpienie EvaluationContext klasy (przekazane jako argument) oświadczeniami opartymi na przychodzącej zawartości tokenu zabezpieczającego. Metoda jest zwracana true po zakończeniu oceny. W przypadkach, gdy implementacja opiera się na obecności innych zasad autoryzacji, które dostarczają dodatkowych informacji do kontekstu oceny, ta metoda może zwrócić false , jeśli wymagane informacje nie są jeszcze obecne w kontekście oceny. W takim przypadku program WCF ponownie wywoła metodę po ocenie wszystkich innych zasad autoryzacji wygenerowanych dla komunikatu przychodzącego, jeśli co najmniej jedna z tych zasad autoryzacji zmodyfikowała kontekst oceny.

    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
    

Przewodnik: Tworzenie niestandardowych poświadczeń klienta i usługi opisuje sposób tworzenia poświadczeń niestandardowych i niestandardowego menedżera tokenów zabezpieczających. Aby użyć niestandardowego wystawcy uwierzytelnienia tokenu zabezpieczającego utworzonego tutaj, implementacja menedżera tokenów zabezpieczających jest modyfikowana w celu zwrócenia niestandardowego wystawcy uwierzytelnienia z CreateSecurityTokenAuthenticator metody . Metoda zwraca wystawcę uwierzytelniającego, gdy zostanie przekazane odpowiednie wymaganie dotyczące tokenu zabezpieczającego.

Aby zintegrować niestandardowy wystawca uwierzytelniania tokenów zabezpieczających z niestandardowym menedżerem tokenów zabezpieczających

  1. Zastąp metodę w niestandardowej CreateSecurityTokenAuthenticator implementacji menedżera tokenów zabezpieczających.

  2. Dodaj logikę do metody , aby umożliwić jej zwrócenie niestandardowego wystawcy uwierzytelnienie tokenu zabezpieczającego na podstawie parametru SecurityTokenRequirement . Poniższy przykład zwraca niestandardowy wystawcę uwierzytelnienia tokenu zabezpieczającego, jeśli typ tokenu wymagania tokenu jest nazwą użytkownika (reprezentowaną przez UserName właściwość), a kierunek komunikatu, dla którego żądany wystawca uwierzytelnienia tokenu zabezpieczającego jest wejściowy (reprezentowany przez Input pole).

    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
    

Zobacz też