Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Mit dem Identitätsfeature von Windows Communication Foundation (WCF) kann ein Client im Voraus die erwartete Identität des Diensts angeben. Wenn sich ein Server beim Client authentifiziert, wird die Identität anhand der erwarteten Identität überprüft. (Eine Erläuterung der Identität und ihrer Funktionsweise finden Sie unter Dienstidentität und Authentifizierung.)
Bei Bedarf kann die Überprüfung mithilfe einer benutzerdefinierten Identitätsprüfung angepasst werden. Sie können z. B. zusätzliche Überprüfungen der Dienstidentität durchführen. In diesem Beispiel überprüft die benutzerdefinierte Identitätsprüfung zusätzliche Ansprüche im vom Server zurückgegebenen X.509-Zertifikat. Eine Beispielanwendung finden Sie unter Service Identity Sample.
So erweitern Sie die EndpointIdentity-Klasse
Definieren Sie eine neue Klasse, die von der EndpointIdentity Klasse abgeleitet wird. In diesem Beispiel wird die Erweiterung
OrgEndpointIdentitybenannt.Fügen Sie private Mitglieder und Eigenschaften hinzu, die von der erweiterten IdentityVerifier Klasse verwendet werden, um die Identitätsprüfung für Ansprüche im Sicherheitstoken durchzuführen, das vom Dienst zurückgegeben wird. In diesem Beispiel wird eine Eigenschaft definiert: die
OrganizationClaimEigenschaft.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
So erweitern Sie die IdentityVerifier-Klasse
Definieren Sie eine neue Klasse, die von IdentityVerifier. In diesem Beispiel wird die Erweiterung
CustomIdentityVerifierbenannt.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Überschreiben Sie die CheckAccess Methode. Die Methode bestimmt, ob die Identitätsprüfung erfolgreich war oder fehlgeschlagen ist.
Die
CheckAccessMethode hat zwei Parameter. Der erste ist eine Instanz der EndpointIdentity Klasse. Die zweite ist eine Instanz der AuthorizationContext Klasse.Untersuchen Sie in der Methodenimplementierung die Sammlung von Ansprüchen, die von der ClaimSets Eigenschaft der AuthorizationContext Klasse zurückgegeben werden, und führen Sie Authentifizierungsprüfungen nach Bedarf aus. Dieses Beispiel beginnt mit dem Suchen eines Anspruchs vom Typ "Distinguished Name" und vergleicht dann den Namen mit der Erweiterung der 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: {claim.ClaimType}"); Console.WriteLine($"Right: {claim.Right}"); Console.WriteLine($"Resource: {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
So implementieren Sie die TryGetIdentity-Methode
Implementieren Sie die TryGetIdentity Methode, die bestimmt, ob eine Instanz der EndpointIdentity Klasse vom Client zurückgegeben werden kann. Die WCF-Infrastruktur ruft zuerst die Implementierung der
TryGetIdentityMethode auf, um die Identität des Diensts aus der Nachricht abzurufen. Als Nächstes ruft die Infrastruktur die Implementierung vonCheckAccessmit der zurückgegebenenEndpointIdentityund AuthorizationContext auf.Fügen Sie in der
TryGetIdentityMethode den folgenden Code ein: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
So implementieren Sie eine benutzerdefinierte Bindung und legen den benutzerdefinierten IdentityVerifier fest
Erstellen Sie eine Methode, die ein Binding Objekt zurückgibt. In diesem Beispiel wird eine Instanz der WSHttpBinding Klasse erstellt, der Sicherheitsmodus auf Message gesetzt und ClientCredentialType auf None eingestellt.
Erstellen Sie eine BindingElementCollection mithilfe der CreateBindingElements Methode.
Geben Sie das SecurityBindingElement aus der Sammlung zurück und konvertieren es in eine SymmetricSecurityBindingElement-Variable.
Legen Sie die IdentityVerifier Eigenschaft der LocalClientSecuritySettings Klasse auf eine neue Instanz der
CustomIdentityVerifierzuvor erstellten Klasse fest.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 FunctionDie zurückgegebene benutzerdefinierte Bindung wird verwendet, um eine Instanz des Clients und der Klasse zu erstellen. Der Client kann dann eine benutzerdefinierte Identitätsüberprüfung des Diensts ausführen, wie im folgenden Code dargestellt.
using (CalculatorClient client = new CalculatorClient(customSecurityBinding, serviceAddress)) {Using client As New CalculatorClient(customSecurityBinding, serviceAddress)
Beispiel 1
Das folgende Beispiel zeigt eine vollständige Implementierung der IdentityVerifier Klasse.
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: {claim.ClaimType}");
Console.WriteLine($"Right: {claim.Right}");
Console.WriteLine($"Resource: {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
Beispiel 2
Das folgende Beispiel zeigt eine vollständige Implementierung der EndpointIdentity Klasse.
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