不确定这是否会对您有所帮助,但 ClaimsAuthorizationManager 具有可被覆盖的方法 (LoadCustomConfiguration),您可以使用该方法从 XML 文件加载策略。该策略的设计方式可能允许在资源、操作和角色之间进行映射。我已经建立了代码内访问控制列表,而不是如下所示:
public interface IAccessControlList
{
List<CustomAccessRule> Rules { get; }
}
public class CustomAccessRule
{
public string Operation { get; set; }
public List<string> Roles { get; set; }
public CustomAccessRule(string operation, params string[] roles)
{
Operation = operation;
Roles = roles.ToList();
}
}
我的索赔授权管理器如下所示:
public class CustomClaimsAuthorizationManager : ClaimsAuthorizationManager
{
private IAccessControlList _accessControlList;
public CustomClaimsAuthorizationManager(IAccessControlList accessControlList)
{
_accessControlList = accessControlList;
}
public override bool CheckAccess(AuthorizationContext context)
{
string operation = context.Action.First().Value.Split('/').Last();
CustomAccessRule rule = _accessControlList.Rules.FirstOrDefault(x => x.Operation == operation);
if (rule == null) return true;
if (context.Principal.Identities.First().IsInRoles(rule.Roles)) return true;
throw new MessageSecurityException(string.Format("Username {0} does not have access to operation {1}.", context.Principal.Identities.First().Name, operation));
}
}
这是一个服务的一个访问控制列表实现的示例:
public class SampleServiceACL : IAccessControlList
{
public List<CustomAccessRule> Rules { get; private set; }
public SampleServiceACL()
{
Rules = new List<CustomAccessRule>();
Rules.Add(new CustomAccessRule("OpenAccount", "Manager", "Owner"));
Rules.Add(new CustomAccessRule("CloseAccount", "Manager", "Owner"));
Rules.Add(new CustomAccessRule("SendEmail", "User", "Manager", "Owner"));
}
}
我正在使用以下方法在服务主机基础级别应用它:
protected override void OnOpening()
{
base.OnOpening();
IdentityConfiguration identityConfiguration = new IdentityConfiguration();
identityConfiguration.SecurityTokenHandlers.Clear();
identityConfiguration.ClaimsAuthorizationManager = new CustomClaimsAuthorizationManager(new SampleServiceACL());
this.Credentials.IdentityConfiguration = identityConfiguration;
...
}
结果,我根本没有使用属性,所有授权逻辑都集中在 ACL 上的声明授权管理器中。
现在,如果您不喜欢这种方法,并且您仍在追求将检查特定声明的属性,那么您可以从CodeAccessSecurityAttribute派生并实际实现该逻辑。MS开箱即用的东西是好的,但这并不意味着你应该以任何方式坚持下去。检查声明的逻辑也可以作为身份的扩展来实现,即:
public static class IdentityExtensions
{
public static bool IsInRoles(this ClaimsIdentity id, List<string> roles)
{
foreach (string role in roles)
if (id.HasClaim(ClaimTypes.Role, role)) return true;
return false;
}
}
因此,您可以构建扩展、自定义属性,然后在属性中使用扩展来执行验证逻辑。
同样,这只是我已经做过的事情。可能不是您正在寻找的,但它是一种自定义解决方案。