HOW TO:比較宣告
Windows Communication Foundation (WCF) 中的識別模型基礎結構可用來執行授權檢查。因此,比較授權內容中的宣告與執行所要求動作或存取所要求資源所需要的宣告,屬於常見的工作。本主題將說明如何比較宣告,包括內建和自訂的宣告類型。如需詳細資訊身分識別模型的詳細資訊,請參閱使用身分識別模型來管理宣告與授權。
宣告比較需要將宣告中的三個部分 (類型、權限和資源) 與其他宣告的相同部分進行比較,以便判斷兩種宣告是否相等。請參閱下列範例。
Dim c1 As Claim = Claim.CreateNameClaim("someone")
Dim c2 As Claim = Claim.CreateNameClaim("someone")
Claim c1 = Claim.CreateNameClaim("someone");
Claim c2 = Claim.CreateNameClaim("someone");
這兩個宣告的宣告類型都是 Name、權限都是 PossessProperty,而且資源也都是 "someone" 字串。由於宣告的所有三個部分都相等,因此這些宣告本身是相等的。
內建的宣告類型會使用 Equals 方法來進行比較。必要時,則會使用宣告特定的比較程式碼。例如,在下列這兩個指定的使用者主要名稱 (UPN) 宣告中:
Dim c1 As Claim = Claim.CreateUpnClaim("someone@example.com")
Dim c2 As Claim = Claim.CreateUpnClaim("example\someone")
Claim c1 = Claim.CreateUpnClaim("someone@example.com");
Claim c2 = Claim.CreateUpnClaim("example\\someone");
Equals 方法中的比較程式碼會傳回 true,此時是假設 example\someone
會將相同的網域使用者識別為 "someone@example.com"。
自訂的宣告類型也可以使用 Equals 方法來進行比較。不過,在宣告的 Resource 屬性所傳回的類型不同於原始類型的情況下,根據 Equals 方法,只有在 Resource 屬性傳回的值相等時,Equals 才會傳回 true。在某些不適當的情況下,Resource 屬性傳回的自訂類型應該覆寫 Equals 和 GetHashCode 方法,以便執行任何必要的自訂處理。
比較內建的宣告
在兩個特定的 Claim 類別執行個體中,使用 Equals 來進行比較,如下列程式碼所示。
Public Function CompareTwoClaims(ByVal c1 As Claim, ByVal c2 As Claim) As Boolean Return c1.Equals(c2) End Function
public bool CompareTwoClaims(Claim c1, Claim c2) { return c1.Equals(c2); }
比較具有原始資源類型的自訂宣告
對於具有原始資源類型的自訂宣告,可以使用與內建宣告相同的方法來執行比較,如下列程式碼所示。
Public Function CompareTwoClaims(ByVal c1 As Claim, _ ByVal c2 As Claim) As Boolean Return c1.Equals(c2) End Function
public bool CompareTwoClaims(Claim c1, Claim c2) { return c1.Equals(c2); }
對於具有結構或類別架構之資源類型的自訂宣告,資源類型應該覆寫 Equals 方法。
首先,檢查 obj 參數是否為 null,如果是,則傳回 false。
If obj Is Nothing Then Return False
if (obj == null) return false;
接下來,呼叫 ReferenceEquals,然後將 this 和 obj 當做參數傳遞。如果它傳回 true,則傳回 true。
If ReferenceEquals(Me, obj) Then Return True
if (ReferenceEquals(this, obj)) return true;
接下來,嘗試指派 obj 給類別類型的本機變數。如果這個作業失敗,則參考為 null。在這種情況下,將會傳回 false。
執行必要的自訂比較,以便正確地比較目前的宣告與提供的宣告。
範例
下列範例會示範自訂宣告的比較,其中的宣告資源並非原始類型。
Imports System
Imports System.IdentityModel.Claims
Imports System.Security.Permissions
<assembly: SecurityPermission(SecurityAction.RequestMinimum, Execution := True)>
NotInheritable Public Class MyResourceType
' private members
Private textValue As String
Private numberValue As Integer
' Constructors
Public Sub New()
End Sub 'New
Public Sub New(ByVal textVal As String, ByVal numberValue As Integer)
Me.textValue = textVal
Me.numberValue = numberValue
End Sub
' Public properties
Public ReadOnly Property Text() As String
Get
Return Me.textValue
End Get
End Property
Public ReadOnly Property Number() As Integer
Get
Return Me.numberValue
End Get
End Property
' Override Object.Equals to perform a specific comparison.
Public Overrides Function Equals(ByVal obj As [Object]) As Boolean
' If the object being compared to is null then return false.
If obj Is Nothing Then
Return False
End If
' If the object we are being asked to compare ourselves to is us
' then return true.
If ReferenceEquals(Me, obj) Then
Return True
End If
' Try to convert the object we are being asked to compare ourselves to
' into an instance of MyResourceType.
Dim rhs As MyResourceType = CType(obj, MyResourceType)
' If the object being compared to is not an instance of
' MyResourceType then return false.
If rhs Is Nothing Then
Return False
End If
' Return true if members are the same as those of the object
' being asked to compare to; otherwise, return false.
Return Me.textValue = rhs.textValue AndAlso Me.numberValue = rhs.numberValue
End Function
Public Overrides Function GetHashCode() As Integer
Return Me.textValue.GetHashCode() ^ Me.numberValue.GetHashCode()
End Function
End Class
Class Program
Public Shared Sub Main()
' Create two claims.
Dim c1 As New Claim("http://example.org/claims/mycustomclaim", _
New MyResourceType("Martin", 38), Rights.PossessProperty)
Dim c2 As New Claim("http://example.org/claims/mycustomclaim", _
New MyResourceType("Martin", 38), Rights.PossessProperty)
' Compare the claims.
If c1.Equals(c2) Then
Console.WriteLine("Claims are equal")
Else
Console.WriteLine("Claims are not equal")
End If
End Sub
End Class
using System;
using System.IdentityModel.Claims;
using System.Security.Permissions;
[assembly: SecurityPermission(
SecurityAction.RequestMinimum, Execution = true)]
namespace Samples
{
public sealed class MyResourceType
{
// private members
private string text;
private int number;
// Constructors
public MyResourceType()
{
}
public MyResourceType(string text, int number)
{
this.text = text;
this.number = number;
}
// Public properties
public string Text { get { return this.text; } }
public int Number { get { return this.number; } }
// Override Object.Equals to perform specfic comparison
public override bool Equals(Object obj)
{
// If the object we're being asked to compare ourselves to is null
// then return false
if (obj == null)
return false;
// If the object we're being asked to compare ourselves to is us
// then return true
if (ReferenceEquals(this, obj))
return true;
// Try to convert the object we're being asked to compare ourselves to
// into an instance of MyResourceType
MyResourceType rhs = obj as MyResourceType;
// If the object we're being asked to compare ourselves to
// isn't an instance of MyResourceType then return false
if (rhs == null)
return false;
// Return true if our members are the same as those of the object
// we're being asked to compare ourselves to. Otherwise return false
return (this.text == rhs.text && this.number == rhs.number);
}
public override int GetHashCode()
{
return (this.text.GetHashCode() ^ this.number.GetHashCode());
}
}
class Program
{
public static void Main()
{
// Create two claims
Claim c1 = new Claim("http://example.org/claims/mycustomclaim",
new MyResourceType("Martin", 38), Rights.PossessProperty);
Claim c2 = new Claim("http://example.org/claims/mycustomclaim",
new MyResourceType("Martin", 38), Rights.PossessProperty);
// Compare the claims
if (c1.Equals(c2))
Console.WriteLine("Claims are equal");
else
Console.WriteLine("Claims are not equal");
}
}
}