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
Zdefiniuj nową klasę pochodzącą SecurityTokenAuthenticator z klasy .
Zastąpij metodę CanValidateTokenCore . Metoda zwraca
true
lubfalse
w zależności od tego, czy niestandardowy wystawca uwierzytelniający może zweryfikować typ tokenu przychodzącego, czy nie.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
Zdefiniuj nową klasę implementowania interfejsu IAuthorizationPolicy .
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.
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.
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
Zastąp metodę w niestandardowej CreateSecurityTokenAuthenticator implementacji menedżera tokenów zabezpieczających.
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