Anvisningar: Skapa en anpassad klientidentitetsverifierare
Identitetsfunktionen i Windows Communication Foundation (WCF) gör det möjligt för en klient att i förväg ange den förväntade identiteten för tjänsten. När en server autentiserar sig mot klienten kontrolleras identiteten mot den förväntade identiteten. (En förklaring av identiteten och hur den fungerar finns i Tjänstidentitet och autentisering.)
Om det behövs kan verifieringen anpassas med hjälp av en anpassad identitetsverifierare. Du kan till exempel utföra ytterligare kontroller av tjänstidentitetsverifiering. I det här exemplet kontrollerar den anpassade identitetsverifieraren ytterligare anspråk i X.509-certifikatet som returneras från servern. Ett exempelprogram finns i Exempel på tjänstidentitet.
Utöka endpointIdentity-klassen
Definiera en ny klass som härleds från EndpointIdentity klassen. I det här exemplet namnges tillägget
OrgEndpointIdentity
.Lägg till privata medlemmar tillsammans med egenskaper som ska användas av den utökade IdentityVerifier klassen för att utföra identitetskontrollen mot anspråk i säkerhetstoken som returneras från tjänsten. Det här exemplet definierar en egenskap: egenskapen
OrganizationClaim
.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
Utöka klassen IdentityVerifier
Definiera en ny klass som härleds från IdentityVerifier. I det här exemplet namnges tillägget
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
Åsidosätt CheckAccess metoden. Metoden avgör om identitetskontrollen lyckades eller misslyckades.
Metoden
CheckAccess
har två parametrar. Den första är en instans av EndpointIdentity klassen. Den andra är en instans av AuthorizationContext klassen.I metodimplementeringen undersöker du samlingen av anspråk som returneras av ClaimSets klassens egenskap AuthorizationContext och utför autentiseringskontroller efter behov. Det här exemplet börjar med att hitta ett anspråk som är av typen "Unikt namn" och jämför sedan namnet med tillägget EndpointIdentity för (
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
Så här implementerar du metoden TryGetIdentity
TryGetIdentity Implementera metoden som avgör om en instans av EndpointIdentity klassen kan returneras av klienten. WCF-infrastrukturen anropar implementeringen av
TryGetIdentity
metoden först för att hämta tjänstens identitet från meddelandet. Därefter anropar infrastrukturen implementeringenCheckAccess
med returneradeEndpointIdentity
och AuthorizationContext.TryGetIdentity
I -metoden anger du följande kod: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
Implementera en anpassad bindning och ange den anpassade IdentityVerifier
Skapa en metod som returnerar ett Binding objekt. Det här exemplet börjar skapar en instans av WSHttpBinding klassen och anger dess säkerhetsläge till Message, och dess ClientCredentialType till None.
Skapa en BindingElementCollection med hjälp av CreateBindingElements metoden .
SecurityBindingElement Returnera från samlingen och omvandla den till en SymmetricSecurityBindingElement variabel.
IdentityVerifier Ange egenskapen för LocalClientSecuritySettings klassen till en ny instans av klassen som
CustomIdentityVerifier
skapades tidigare.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
Den anpassade bindning som returneras används för att skapa en instans av klienten och klassen. Klienten kan sedan utföra en anpassad identitetsverifieringskontroll av tjänsten enligt följande kod.
using (CalculatorClient client = new CalculatorClient(customSecurityBinding, serviceAddress)) {
Using client As New CalculatorClient(customSecurityBinding, serviceAddress)
Exempel 1
I följande exempel visas en fullständig implementering av IdentityVerifier klassen.
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
Exempel 2
I följande exempel visas en fullständig implementering av EndpointIdentity klassen.
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