Dela via


Så här skapar du en anpassad autentiseringstoken för säkerhetstoken

Det här avsnittet visar hur du skapar en anpassad säkerhetstokenautentisering och hur du integrerar den med en anpassad säkerhetstokenhanterare. En autentisering av säkerhetstoken verifierar innehållet i en säkerhetstoken som tillhandahålls med ett inkommande meddelande. Om valideringen lyckas returnerar autentiseringen en samling IAuthorizationPolicy instanser som, när den utvärderas, returnerar en uppsättning anspråk.

Om du vill använda en anpassad säkerhetstokenautentisering i Windows Communication Foundation (WCF) måste du först skapa anpassade autentiseringsuppgifter och implementeringar av säkerhetstokenhanteraren. Mer information om hur du skapar anpassade autentiseringsuppgifter och en säkerhetstokenhanterare finns i Genomgång: Skapa anpassade klient- och tjänstautentiseringsuppgifter.

Förfaranden

Skapa en anpassad autentiseringstoken för säkerhetstoken

  1. Definiera en ny klass som härleds SecurityTokenAuthenticator från klassen.

  2. Åsidosätt CanValidateTokenCore metoden. Metoden returnerar true eller false beroende på om den anpassade autentiseringen kan verifiera den inkommande tokentypen eller inte.

  3. Åsidosätt ValidateTokenCore metoden. Den här metoden måste verifiera tokeninnehållet på rätt sätt. Om token klarar valideringssteget returneras en samling IAuthorizationPolicy instanser. I följande exempel används en implementering av en anpassad auktoriseringsprincip som kommer att skapas i nästa procedur.

    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
    

Den tidigare koden returnerar en samling auktoriseringsprinciper i CanValidateToken(SecurityToken) metoden. WCF tillhandahåller ingen offentlig implementering av det här gränssnittet. Följande procedur visar hur du gör det för dina egna krav.

Skapa en anpassad auktoriseringsprincip

  1. Definiera en ny klass som implementerar IAuthorizationPolicy gränssnittet.

  2. Implementera den Id skrivskyddade egenskapen. Ett sätt att implementera den här egenskapen är att generera en globalt unik identifierare (GUID) i klasskonstruktorn och returnera den varje gång värdet för den här egenskapen begärs.

  3. Implementera den Issuer skrivskyddade egenskapen. Den här egenskapen måste returnera en utfärdare av anspråksuppsättningarna som hämtas från token. Den här utfärdaren bör motsvara utfärdaren av token eller en utfärdare som ansvarar för att verifiera tokeninnehållet. I följande exempel används utfärdaranspråket som skickades till den här klassen från den anpassade säkerhetstokenautentisering som skapades i föregående procedur. Den anpassade säkerhetstokenutentiseraren använder den systembaserade anspråksuppsättningen System (som returneras av egenskapen) för att representera utfärdaren av användarnamnstoken.

  4. Evaluate Implementera metoden. Den här metoden fyller i en instans av EvaluationContext klassen (skickas som ett argument) med anspråk som baseras på innehållet i den inkommande säkerhetstoken. Metoden returnerar true när den är klar med utvärderingen. I de fall då implementeringen förlitar sig på förekomsten av andra auktoriseringsprinciper som ger ytterligare information till utvärderingskontexten kan den här metoden returneras false om nödvändig information ännu inte finns i utvärderingskontexten. I så fall anropar WCF metoden igen efter att ha utvärderat alla andra auktoriseringsprinciper som genererats för det inkommande meddelandet om minst en av dessa auktoriseringsprinciper ändrade utvärderingskontexten.

    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
    

Genomgång: När du skapar autentiseringsuppgifter för anpassad klient och tjänst beskrivs hur du skapar anpassade autentiseringsuppgifter och en anpassad säkerhetstokenhanterare. Om du vill använda den anpassade autentiseringsnyckeln som skapats här ändras en implementering av säkerhetstokenhanteraren för att returnera den anpassade autentiseringen från CreateSecurityTokenAuthenticator metoden. Metoden returnerar en autentisering när ett lämpligt krav för säkerhetstoken skickas.

Så här integrerar du en anpassad säkerhetstokenautentisering med en anpassad säkerhetstokenhanterare

  1. Åsidosätt metoden i implementeringen av CreateSecurityTokenAuthenticator din anpassade säkerhetstokenhanterare.

  2. Lägg till logik i metoden så att den kan returnera din anpassade säkerhetstokenautentisering baserat på parametern SecurityTokenRequirement . I följande exempel returneras en anpassad autentisering av säkerhetstoken om tokentypen token för tokenkrav är ett användarnamn (representeras av UserName egenskapen) och meddelanderiktningen som autentiseringsnyckeln begärs för är indata (representeras av Input fältet).

    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
    

Se även