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í
Definujte novou třídu odvozenou SecurityTokenAuthenticator z třídy.
Přepište metodu CanValidateTokenCore . Metoda vrátí
true
nebofalse
v závislosti na tom, jestli může vlastní ověřovací objekt ověřit typ příchozího tokenu, nebo ne.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
Definujte novou třídu, která implementuje IAuthorizationPolicy rozhraní.
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.
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.
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átitfalse
, 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í
Přepište metodu CreateSecurityTokenAuthenticator ve vlastní implementaci správce tokenů zabezpečení.
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