Postupy: Vytvoření vlastního ověřovatele identity klientů
Funkce identity technologie Windows Communication Foundation (WCF) umožňuje klientovi zadat předem očekávanou identitu služby. Pokaždé, když se server ověří vůči klientovi, identita se zkontroluje podle očekávané identity. (Vysvětlení identity a jeho fungování najdete v tématu .Identita a ověřování služby.)
V případě potřeby je možné ověření přizpůsobit pomocí vlastního ověřovatele identity. Můžete například provést další kontroly ověření identity služby. V tomto příkladu ověří vlastní identita další deklarace identity v certifikátu X.509 vráceného ze serveru. Ukázkovou aplikaci najdete v části Ukázka identity služby.
Rozšíření třídy EndpointIdentity
Definujte novou třídu, která je odvozena od EndpointIdentity třídy. Tento příklad pojmenuje příponu
OrgEndpointIdentity
.Přidejte soukromé členy spolu s vlastnostmi, které bude rozšířená IdentityVerifier třída používat k provedení kontroly identity proti deklarací identity v tokenu zabezpečení vráceného ze služby. Tento příklad definuje jednu vlastnost:
OrganizationClaim
vlastnost.public class OrgEndpointIdentity : EndpointIdentity { private string orgClaim; public OrgEndpointIdentity(string orgName) { orgClaim = orgName; } public string OrganizationClaim { get { return orgClaim; } set { orgClaim = value; } } }
Public Class OrgEndpointIdentity Inherits EndpointIdentity Private orgClaim As String Public Sub New(ByVal orgName As String) orgClaim = orgName End Sub Public Property OrganizationClaim() As String Get Return orgClaim End Get Set(ByVal value As String) orgClaim = value End Set End Property End Class
Rozšíření třídy IdentityVerifier
Definujte novou třídu, která je odvozena od IdentityVerifier. Tento příklad pojmenuje příponu
CustomIdentityVerifier
.public class CustomIdentityVerifier : IdentityVerifier { // Code to be added. public override bool CheckAccess(EndpointIdentity identity, AuthorizationContext authContext) { throw new Exception("The method or operation is not implemented."); } public override bool TryGetIdentity(EndpointAddress reference, out EndpointIdentity identity) { throw new Exception("The method or operation is not implemented."); } }
Public Class CustomIdentityVerifier Inherits IdentityVerifier ' Code to be added. Public Overrides Function CheckAccess(ByVal identity As EndpointIdentity, _ ByVal authContext As AuthorizationContext) As Boolean Throw New Exception("The method or operation is not implemented.") End Function Public Overrides Function TryGetIdentity(ByVal reference As EndpointAddress, _ <System.Runtime.InteropServices.Out()> ByRef identity As EndpointIdentity) As Boolean Throw New Exception("The method or operation is not implemented.") End Function End Class
Přepište metodu CheckAccess . Metoda určuje, jestli kontrola identity proběhla úspěšně nebo selhala.
Metoda
CheckAccess
má dva parametry. První je instance EndpointIdentity třídy. Druhým je instance AuthorizationContext třídy.V implementaci metody prozkoumejte kolekci deklarací vrácených ClaimSetsAuthorizationContext vlastností třídy a podle potřeby proveďte kontroly ověřování. Tento příklad začíná vyhledáním jakékoli deklarace identity typu "Rozlišující název" a pak porovná název s příponou EndpointIdentity (
OrgEndpointIdentity
).public override bool CheckAccess(EndpointIdentity identity, AuthorizationContext authContext) { bool returnvalue = false; foreach (ClaimSet claimset in authContext.ClaimSets) { foreach (Claim claim in claimset) { if (claim.ClaimType == "http://schemas.microsoft.com/ws/2005/05/identity/claims/x500distinguishedname") { X500DistinguishedName name = (X500DistinguishedName)claim.Resource; if (name.Name.Contains(((OrgEndpointIdentity)identity).OrganizationClaim)) { Console.WriteLine("Claim Type: {0}", claim.ClaimType); Console.WriteLine("Right: {0}", claim.Right); Console.WriteLine("Resource: {0}", claim.Resource); Console.WriteLine(); returnvalue = true; } } } } return returnvalue; }
Public Overrides Function CheckAccess(ByVal identity As EndpointIdentity, _ ByVal authContext As AuthorizationContext) As Boolean Dim returnvalue = False For Each claimset In authContext.ClaimSets For Each claim In claimset If claim.ClaimType = "http://schemas.microsoft.com/ws/2005/05/identity/claims/x500distinguishedname" Then Dim name = CType(claim.Resource, X500DistinguishedName) If name.Name.Contains((CType(identity, OrgEndpointIdentity)).OrganizationClaim) Then Console.WriteLine("Claim Type: {0}", claim.ClaimType) Console.WriteLine("Right: {0}", claim.Right) Console.WriteLine("Resource: {0}", claim.Resource) Console.WriteLine() returnvalue = True End If End If Next claim Next claimset Return returnvalue End Function
Implementace metody TryGetIdentity
Implementujte metodu TryGetIdentity , která určuje, zda může klient vrátit instanci EndpointIdentity třídy. Infrastruktura WCF nejprve volá implementaci
TryGetIdentity
metody k načtení identity služby ze zprávy. Dále infrastruktura volá implementaciCheckAccess
s vrácenouEndpointIdentity
a AuthorizationContext.TryGetIdentity
Do metody vložte následující kód:public override bool TryGetIdentity(EndpointAddress reference, out EndpointIdentity identity) { return IdentityVerifier.CreateDefault().TryGetIdentity(reference, out identity); }
Public Overrides Function TryGetIdentity(ByVal reference As EndpointAddress, _ <System.Runtime.InteropServices.Out()> ByRef identity As EndpointIdentity) As Boolean Return IdentityVerifier.CreateDefault().TryGetIdentity(reference, identity) End Function
Implementace vlastní vazby a nastavení vlastního identityVerifier
Vytvořte metodu Binding , která vrací objekt. Tento příklad začíná vytvořit instanci WSHttpBinding třídy a nastaví její režim zabezpečení na Message, a jeho ClientCredentialType na None.
Vytvořte pomocí BindingElementCollectionCreateBindingElements metody.
SecurityBindingElement Vrátí z kolekce a přetypuje ji do SymmetricSecurityBindingElement proměnné.
IdentityVerifier Nastavte vlastnost LocalClientSecuritySettings třídy na novou instanci
CustomIdentityVerifier
třídy vytvořené dříve.public static Binding CreateCustomSecurityBinding() { WSHttpBinding binding = new WSHttpBinding(SecurityMode.Message); //Clients are anonymous to the service. binding.Security.Message.ClientCredentialType = MessageCredentialType.None; //Secure conversation is turned off for simplification. If secure conversation is turned on, then //you also need to set the IdentityVerifier on the secureconversation bootstrap binding. binding.Security.Message.EstablishSecurityContext = false; // Get the SecurityBindingElement and cast to a SymmetricSecurityBindingElement to set the IdentityVerifier. BindingElementCollection outputBec = binding.CreateBindingElements(); SymmetricSecurityBindingElement ssbe = (SymmetricSecurityBindingElement)outputBec.Find<SecurityBindingElement>(); //Set the Custom IdentityVerifier. ssbe.LocalClientSettings.IdentityVerifier = new CustomIdentityVerifier(); return new CustomBinding(outputBec); }
Public Shared Function CreateCustomSecurityBinding() As Binding Dim binding As New WSHttpBinding(SecurityMode.Message) With binding.Security.Message 'Clients are anonymous to the service. .ClientCredentialType = MessageCredentialType.None 'Secure conversation is turned off for simplification. If secure conversation is turned on, then 'you also need to set the IdentityVerifier on the secureconversation bootstrap binding. .EstablishSecurityContext = False End With ' Get the SecurityBindingElement and cast to a SymmetricSecurityBindingElement to set the IdentityVerifier. Dim outputBec = binding.CreateBindingElements() Dim ssbe = CType(outputBec.Find(Of SecurityBindingElement)(), SymmetricSecurityBindingElement) 'Set the Custom IdentityVerifier. ssbe.LocalClientSettings.IdentityVerifier = New CustomIdentityVerifier() Return New CustomBinding(outputBec) End Function
Vrácené vlastní vazby slouží k vytvoření instance klienta a třídy. Klient pak může provést vlastní kontrolu ověření identity služby, jak je znázorněno v následujícím kódu.
using (CalculatorClient client = new CalculatorClient(customSecurityBinding, serviceAddress)) {
Using client As New CalculatorClient(customSecurityBinding, serviceAddress)
Příklad 1
Následující příklad ukazuje úplnou implementaci IdentityVerifier třídy.
class CustomIdentityVerifier : IdentityVerifier
{
public override bool CheckAccess(EndpointIdentity identity, AuthorizationContext authContext)
{
bool returnvalue = false;
foreach (ClaimSet claimset in authContext.ClaimSets)
{
foreach (Claim claim in claimset)
{
if (claim.ClaimType == "http://schemas.microsoft.com/ws/2005/05/identity/claims/x500distinguishedname")
{
X500DistinguishedName name = (X500DistinguishedName)claim.Resource;
if (name.Name.Contains(((OrgEndpointIdentity)identity).OrganizationClaim))
{
Console.WriteLine("Claim Type: {0}", claim.ClaimType);
Console.WriteLine("Right: {0}", claim.Right);
Console.WriteLine("Resource: {0}", claim.Resource);
Console.WriteLine();
returnvalue = true;
}
}
}
}
return returnvalue;
}
public override bool TryGetIdentity(EndpointAddress reference, out EndpointIdentity identity)
{
return IdentityVerifier.CreateDefault().TryGetIdentity(reference, out identity);
}
}
Friend Class CustomIdentityVerifier
Inherits IdentityVerifier
Public Overrides Function CheckAccess(ByVal identity As EndpointIdentity, _
ByVal authContext As AuthorizationContext) As Boolean
Dim returnvalue = False
For Each claimset In authContext.ClaimSets
For Each claim In claimset
If claim.ClaimType = "http://schemas.microsoft.com/ws/2005/05/identity/claims/x500distinguishedname" Then
Dim name = CType(claim.Resource, X500DistinguishedName)
If name.Name.Contains((CType(identity, OrgEndpointIdentity)).OrganizationClaim) Then
Console.WriteLine("Claim Type: {0}", claim.ClaimType)
Console.WriteLine("Right: {0}", claim.Right)
Console.WriteLine("Resource: {0}", claim.Resource)
Console.WriteLine()
returnvalue = True
End If
End If
Next claim
Next claimset
Return returnvalue
End Function
Public Overrides Function TryGetIdentity(ByVal reference As EndpointAddress, _
<System.Runtime.InteropServices.Out()> ByRef identity As EndpointIdentity) As Boolean
Return IdentityVerifier.CreateDefault().TryGetIdentity(reference, identity)
End Function
End Class
Příklad 2
Následující příklad ukazuje úplnou implementaci EndpointIdentity třídy.
public class OrgEndpointIdentity : EndpointIdentity
{
private string orgClaim;
public OrgEndpointIdentity(string orgName)
{
orgClaim = orgName;
}
public string OrganizationClaim
{
get { return orgClaim; }
set { orgClaim = value; }
}
}
Public Class OrgEndpointIdentity
Inherits EndpointIdentity
Private orgClaim As String
Public Sub New(ByVal orgName As String)
orgClaim = orgName
End Sub
Public Property OrganizationClaim() As String
Get
Return orgClaim
End Get
Set(ByVal value As String)
orgClaim = value
End Set
End Property
End Class