権限は役割よりもはるかに複雑です。
多くの場合、CreateEditDelete ...などの権限グループが存在する可能性がありますが、「作成」、「編集」、「削除」などの詳細なサブセットにすることもできます。
この問題を解決する方法は、ユーザーがビジネスルールコンテキストとそのADロールに与える必要のあるアクセス許可を決定できるPermissionsMangerクラスを作成することです。
きめ細かい権限の複雑さを単純化するために、ビット単位のフラグを使用しました。
ロールを権限にマップする方法は完全にあなた次第です。
using System;
using System.Linq;
using System.Security.Principal;
// Install-Package FluentAssertions -Pre
using FluentAssertions;
public static class ExtensionsForIPrincipal
{
public static bool HasPermission(this IPrincipal principal, Permissions permission)
{
return PermissionsManager.GetUserPermissions(principal).HasFlag(permission);
}
public static bool IsInRole(this IPrincipal principal, params string[] roleNames)
{
return roleNames.Any(principal.IsInRole);
}
}
public static class PermissionsManager
{
public static Permissions GetUserPermissions(IPrincipal user)
{
if ( user.IsInRole("admin") )
{
return Permissions.All;
}
var userPermissions = Permissions.None;
if ( user.IsInRole("staff", "user") )
{
userPermissions |= Permissions.QueryUsers;
}
if ( user.IsInRole("staff") )
{
userPermissions |= Permissions.PermissionsCreateEditDeleteSomething | Permissions.QueryUsers;
}
if ( user.IsInRole("editor") )
{
userPermissions |= Permissions.PublishSomething;
}
return userPermissions;
}
}
[Flags]
public enum Permissions
{
None = 0,
CreateSomething = 1,
EditSomething = 2,
DeleteSomething = 4,
PublishSomething = 8,
QueryUsers = 16,
PermissionsCreateEditDeleteSomething = CreateSomething | EditSomething | DeleteSomething,
All = PermissionsCreateEditDeleteSomething | PublishSomething | QueryUsers
}
internal class Program
{
private static void Main(string[] args)
{
IPrincipal admin = Create("james", "admin");
PermissionsManager.GetUserPermissions(admin).ShouldBeEquivalentTo(Permissions.All);
admin.HasPermission(Permissions.None).Should().BeTrue();
admin.HasPermission(Permissions.EditSomething).Should().BeTrue();
admin.HasPermission(Permissions.PermissionsCreateEditDeleteSomething).Should().BeTrue();
admin.HasPermission(Permissions.PublishSomething).Should().BeTrue();
admin.HasPermission(Permissions.QueryUsers).Should().BeTrue();
admin.HasPermission(Permissions.All).Should().BeTrue();
IPrincipal editor = Create("susan", "editor", "staff");
editor.HasPermission(Permissions.None).Should().BeTrue();
editor.HasPermission(Permissions.EditSomething).Should().BeTrue();
editor.HasPermission(Permissions.PermissionsCreateEditDeleteSomething).Should().BeTrue();
editor.HasPermission(Permissions.QueryUsers).Should().BeTrue();
editor.HasPermission(Permissions.PublishSomething).Should().BeTrue();
editor.HasPermission(Permissions.All).Should().BeTrue();
IPrincipal staff = Create("michael", "staff");
staff.HasPermission(Permissions.None).Should().BeTrue();
staff.HasPermission(Permissions.EditSomething | Permissions.DeleteSomething).Should().BeTrue();
staff.HasPermission(Permissions.PermissionsCreateEditDeleteSomething).Should().BeTrue();
staff.HasPermission(Permissions.QueryUsers).Should().BeTrue();
staff.HasPermission(Permissions.PublishSomething).Should().BeFalse();
staff.HasPermission(Permissions.All).Should().BeFalse();
IPrincipal user = Create("bob", "user");
user.HasPermission(Permissions.None).Should().BeTrue();
user.HasPermission(Permissions.EditSomething).Should().BeFalse();
user.HasPermission(Permissions.PermissionsCreateEditDeleteSomething).Should().BeFalse();
user.HasPermission(Permissions.QueryUsers).Should().BeTrue();
user.HasPermission(Permissions.PublishSomething).Should().BeFalse();
user.HasPermission(Permissions.All).Should().BeFalse();
IPrincipal anon = Create("anonymous");
anon.HasPermission(Permissions.None).Should().BeTrue();
anon.HasPermission(Permissions.EditSomething).Should().BeFalse();
anon.HasPermission(Permissions.PermissionsCreateEditDeleteSomething).Should().BeFalse();
anon.HasPermission(Permissions.QueryUsers).Should().BeFalse();
anon.HasPermission(Permissions.PublishSomething).Should().BeFalse();
anon.HasPermission(Permissions.All).Should().BeFalse();
Console.WriteLine("All tests passed");
Console.ReadLine();
}
private static IPrincipal Create(string name, params string[] roles)
{
return new GenericPrincipal(new GenericIdentity(name), roles);
}
}