Cara untuk: Membuat Pemverifikasi Identitas Klien Kustom
Fitur identitas Windows Communication Foundation (WCF) memungkinkan klien menentukan terlebih dahulu identitas layanan yang diharapkan. Setiap kali server mengautentikasi dirinya sendiri ke klien, identitas diperiksa terhadap identitas yang diharapkan. (Untuk penjelasan tentang identitas dan cara kerjanya, lihat Identitas dan Autentikasi Layanan.)
Jika diperlukan, verifikasi dapat disesuaikan menggunakan pemverifikasi identitas kustom. Misalnya, Anda dapat melakukan pemeriksaan verifikasi identitas layanan tambahan. Dalam contoh ini, pemverifikasi identitas kustom memeriksa klaim tambahan dalam sertifikat X.509 yang dikembalikan dari server. Untuk aplikasi sampel, lihat Sampel Identitas Layanan.
Untuk memperluas kelas EndpointIdentity
Tentukan kelas baru yang berasal dari kelas EndpointIdentity. Contoh ini menamai ekstensi
OrgEndpointIdentity
.Tambahkan anggota privat bersama dengan properti yang akan digunakan oleh kelas IdentityVerifier yang diperluas untuk melakukan pemeriksaan identitas terhadap klaim dalam token keamanan yang dikembalikan dari layanan. Contoh ini mendefinisikan satu properti: properti
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
Untuk memperluas kelas IdentityVerifier
Tentukan kelas baru yang berasal dari IdentityVerifier. Contoh ini menamai ekstensi
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
Ambil alih metode CheckAccess. Metode menentukan apakah pemeriksaan identitas berhasil atau gagal.
Metode
CheckAccess
membutuhkan dua parameter. Yang pertama adalah instans kelas EndpointIdentity. Yang kedua adalah instans kelas AuthorizationContext.Dalam implementasi metode, periksa pengumpulan klaim yang dikembalikan oleh properti ClaimSets kelas AuthorizationContext, dan lakukan pemeriksaan autentikasi sesuai kebutuhan. Contoh ini dimulai dengan menemukan klaim apa pun yang berjenis "Nama Yang Dibedakan" lalu membandingkan nama dengan ekstensi 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
Untuk menerapkan metode TryGetIdentity
Terapkan metode TryGetIdentity, yang menentukan apakah instans kelas EndpointIdentity dapat dikembalikan oleh klien. Infrastruktur WCF memanggil implementasi metode
TryGetIdentity
terlebih dahulu untuk mengambil identitas layanan dari pesan. Selanjutnya, infrastruktur memanggil implementasiCheckAccess
denganEndpointIdentity
dan AuthorizationContext yang dikembalikan.Dalam metode
TryGetIdentity
, masukkan kode berikut: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
Untuk menerapkan pengikatan kustom dan mengatur IdentityVerifier kustom
Buat metode yang mengembalikan objek Binding. Contoh ini mulai membuat instans kelas WSHttpBinding dan mengatur mode keamanannya ke Message, dan ClientCredentialTypenya ke None.
Buat BindingElementCollection menggunakan metode CreateBindingElements.
Kembalikan SecurityBindingElement dari koleksi dan transmisikan ke variabel SymmetricSecurityBindingElement.
Atur properti IdentityVerifier kelas LocalClientSecuritySettings ke instans baru kelas
CustomIdentityVerifier
yang dibuat sebelumnya.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
Pengikatan kustom yang dikembalikan digunakan untuk membuat instans klien dan kelas. Klien kemudian dapat melakukan pemeriksaan verifikasi identitas kustom layanan seperti yang ditunjukkan dalam kode berikut.
using (CalculatorClient client = new CalculatorClient(customSecurityBinding, serviceAddress)) {
Using client As New CalculatorClient(customSecurityBinding, serviceAddress)
Contoh 1
Contoh berikut menunjukkan implementasi lengkap kelas IdentityVerifier.
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
Contoh 2
Contoh berikut menunjukkan implementasi lengkap kelas EndpointIdentity.
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