Postupy: Vytvoření vlastního ověřovacího tokenu zabezpečení

Toto téma ukazuje, jak vytvořit vlastní ověřovací token zabezpečení a jak ho integrovat s vlastním správcem tokenů zabezpečení. Ověřovací token zabezpečení ověří obsah tokenu zabezpečení poskytnutého příchozí zprávou. Pokud ověření proběhne úspěšně, authenticator vrátí kolekci IAuthorizationPolicy instancí, které při vyhodnocení vrátí sadu deklarací identity.

Chcete-li použít vlastní ověřovací token zabezpečení ve Windows Communication Foundation (WCF), musíte nejprve vytvořit vlastní přihlašovací údaje a implementace správce tokenů zabezpečení. Další informace o vytváření vlastních přihlašovacích údajů a správce tokenů zabezpečení naleznete v tématu Návod: Vytvoření vlastních přihlašovacích údajů klienta a služby.

Procedury

Vytvoření vlastního ověřovacího tokenu zabezpečení

  1. Definujte novou třídu odvozenou SecurityTokenAuthenticator z třídy.

  2. Přepište metodu CanValidateTokenCore . Metoda vrátí true nebo false v závislosti na tom, jestli může vlastní ověřovací objekt ověřit typ příchozího tokenu, nebo ne.

  3. Přepište metodu ValidateTokenCore . Tato metoda musí správně ověřit obsah tokenu. Pokud token projde ověřovacím krokem, vrátí kolekci IAuthorizationPolicy instancí. Následující příklad používá vlastní implementaci zásad autorizace, která se vytvoří v dalším postupu.

    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
    

Předchozí kód vrátí kolekci zásad autorizace v CanValidateToken(SecurityToken) metodě. WCF neposkytuje veřejnou implementaci tohoto rozhraní. Následující postup ukazuje, jak to udělat pro vaše vlastní požadavky.

Vytvoření vlastních zásad autorizace

  1. Definujte novou třídu, která implementuje IAuthorizationPolicy rozhraní.

  2. Implementujte vlastnost jen pro Id čtení. Jedním ze způsobů, jak tuto vlastnost implementovat, je vygenerovat globálně jedinečný identifikátor (GUID) v konstruktoru třídy a vrátit ji při každém vyžádání hodnoty této vlastnosti.

  3. Implementujte vlastnost jen pro Issuer čtení. Tato vlastnost musí vrátit vystavitele sad deklarací, které jsou získány z tokenu. Tento vystavitel by měl odpovídat vystavitelu tokenu nebo autoritě, která je zodpovědná za ověření obsahu tokenu. Následující příklad používá deklaraci identity vystavitele, která byla předána této třídě z vlastního ověřovacího objektu tokenu zabezpečení vytvořeného v předchozím postupu. Ověřovací token vlastního tokenu zabezpečení používá sadu deklarací identity poskytovanou systémem (vrácenou System vlastností) k reprezentaci vystavitele tokenu uživatelského jména.

  4. Implementujte metodu Evaluate . Tato metoda naplní instanci třídy (předané jako argument) deklaracemi, které jsou založeny na obsahu příchozího EvaluationContext tokenu zabezpečení. Metoda se vrátí true po dokončení vyhodnocení. V případech, kdy implementace závisí na přítomnosti jiných zásad autorizace, které poskytují další informace do kontextu vyhodnocení, tato metoda může vrátit false , pokud požadované informace ještě nejsou k dispozici v kontextu vyhodnocení. V takovém případě WCF zavolá metodu znovu po vyhodnocení všech ostatních zásad autorizace vygenerovaných pro příchozí zprávu, pokud alespoň jedna z těchto zásad autorizace změnila kontext vyhodnocení.

    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
    

Návod: Vytvoření vlastních přihlašovacích údajů klienta a služby popisuje, jak vytvořit vlastní přihlašovací údaje a vlastního správce tokenů zabezpečení. Chcete-li použít vlastní ověřovací token zabezpečení vytvořený zde, implementace správce tokenů zabezpečení je změněna tak, aby vrátila vlastní ověřovací objekt z CreateSecurityTokenAuthenticator metody. Metoda vrátí ověřovací program, pokud je předán příslušný požadavek na token zabezpečení.

Integrace vlastního ověřovacího tokenu zabezpečení s vlastním správcem tokenů zabezpečení

  1. Přepište metodu CreateSecurityTokenAuthenticator ve vlastní implementaci správce tokenů zabezpečení.

  2. Přidejte do metody logiku, která jí umožní vrátit vlastní ověřovací objekt tokenu zabezpečení na základě parametru SecurityTokenRequirement . Následující příklad vrátí vlastní ověřovací token zabezpečení, pokud typ tokenu požadavků tokenu je uživatelské jméno (reprezentované UserName vlastností) a směr zprávy, pro který se požaduje ověřovací token zabezpečení, je vstup (reprezentovaný polem Input ).

    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
    

Viz také