この記事は、承認をサポートするために WCF が提供するすべてのものの優れた要約であることがわかりました。この記事では、最も単純な実装から始めて、本格的なクレーム ベースの承認に至るまでの、複雑さの段階的な各ステップについて説明します。
特定の状況に関して提供された情報に基づいて、リンクした記事の図 3 に示されているように、IPrincipal のカスタム実装を作成することをお勧めします。記事のコード サンプルもここに含めました。
class CustomPrincipal : IPrincipal
{
IIdentity _identity;
string[] _roles;
Cache _cache = HttpRuntime.Cache;
public CustomPrincipal(IIdentity identity)
{
_identity = identity;
}
// helper method for easy access (without casting)
public static CustomPrincipal Current
{
get
{
return Thread.CurrentPrincipal as CustomPrincipal;
}
}
public IIdentity Identity
{
get { return _identity; }
}
// return all roles (custom property)
public string[] Roles
{
get
{
EnsureRoles();
return _roles;
}
}
// IPrincipal role check
public bool IsInRole(string role)
{
EnsureRoles();
return _roles.Contains(role);
}
// cache roles for subsequent requests
protected virtual void EnsureRoles()
{
// caching logic omitted – see the sample download
}
}
元の投稿で参照されているカスタム ユーザー名とパスワード バリデーターでは、新しい IPrincipal のインスタンスを入力し、それを静的な値 Thread.CurrentPrincipal にアタッチするだけです。これにより、以下に示すように PrincipalPermission 属性を使用して、アクセスを制御したいメソッドを簡単に装飾できます。このコード サンプルも、リンクした記事の図 1 です。
class Service : IService {
// only 'users' role member can call this method
[PrincipalPermission(SecurityAction.Demand, Role = 'users')]
public string[] GetRoles(string username) {
// only administrators can retrieve the role information for other users
if (ServiceSecurityContext.Current.PrimaryIdentity.Name != username) {
if (Thread.CurrentPrincipal.IsInRole('administrators')) {
...
}
else {
// access denied
throw new SecurityException();
}
}
}
}