方法: クレームを比較する
認証チェックを実行するには、Windows Communication Foundation (WCF) の ID モデル インフラストラクチャを使用します。 この場合、一般的なタスクとして、承認コンテキスト内のクレームが、要求されたアクションの実行や要求されたリソースへのアクセスに必要なクレームと比較されます。 このトピックでは、組み込みとカスタム クレームの型を含め、クレームの比較方法について説明します。 ID モデル インフラストラクチャに関する詳細については、「ID モデルを使用したクレームと承認の管理」を参照してください。
クレームの比較では、クレーム間で 3 つの部分 (型、権限、およびリソース) の比較が行われ、等しいかどうかが判断されます。 次の例を参照してください。
Claim c1 = Claim.CreateNameClaim("someone");
Claim c2 = Claim.CreateNameClaim("someone");
Dim c1 As Claim = Claim.CreateNameClaim("someone")
Dim c2 As Claim = Claim.CreateNameClaim("someone")
いずれのクレームにも、クレームの型として Name、権限として PossessProperty、および文字列リソースとして "someone" が設定されています。 クレームの 3 つの部分のすべてが等しいため、この 2 つのクレームは等しくなります。
組み込みのクレームの型の比較には、Equals メソッドを使用します。 必要に応じて、クレーム固有の比較コードが使用されます。 たとえば、次の 2 つのユーザー プリンシパル名 (UPN) 要求を指定すると、Equals メソッドの比較コードは true
を返します。ここでは、someone@example.com
と同じドメイン ユーザーが example\someone
によって識別されることが前提です。
Claim c1 = Claim.CreateUpnClaim("someone@example.com");
Claim c2 = Claim.CreateUpnClaim("example\\someone");
Dim c1 As Claim = Claim.CreateUpnClaim("someone@example.com")
Dim c2 As Claim = Claim.CreateUpnClaim("example\someone")
カスタム クレームの型の比較にも、Equals メソッドを使用できます。 ただし、クレームの Resource プロパティから返された型がプリミティブ型ではない場合、Equals が true
を返すのは、Resource
プロパティから返された値どうしが等しいと Equals メソッドが見なした場合のみです。 これに該当しない場合は、Resource
プロパティから返されたカスタム型で Equals メソッドと GetHashCode メソッドをオーバーライドし、必要なカスタム処理を実行する必要があります。
組み込みのクレームの比較
Claim クラスの 2 つのインスタンスがある場合、次に示すコードのように、Equals を使用して比較します。
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); }
Public Function CompareTwoClaims(ByVal c1 As Claim, _ ByVal c2 As Claim) As Boolean Return c1.Equals(c2) End Function
構造体またはクラスをベースとしたリソース型を含むカスタム クレームでは、そのリソース型で Equals メソッドをオーバーライドする必要があります。
まず、
obj
パラメーターがnull
であるかどうかを確認し、null である場合はfalse
を返します。if (obj == null) return false;
If obj Is Nothing Then Return False
次に、ReferenceEquals を呼び出し、パラメーターとして
this
とobj
を渡します。true
が返されたら、true
を返します。if (ReferenceEquals(this, obj)) return true;
If ReferenceEquals(Me, obj) Then Return True
さらに、
obj
をクラスの型のローカル変数に割り当てます。 この処理が失敗すると、参照がnull
になります。 この場合、false
が返されます。現在のクレームと提供されたクレームを正しく比較するために必要なカスタム比較を実行します。
例
次の例では、クレームの型がプリミティブ型以外のカスタム クレームを比較します。
using System;
using System.IdentityModel.Claims;
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 specific 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");
}
}
}
Imports System.IdentityModel.Claims
Imports System.Security.Permissions
NotInheritable Public Class MyResourceType
' private members
Private textValue As String
Private numberValue As Integer
' Constructors
Public Sub New()
End Sub
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