我不确定这对你是否有帮助,但是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;
}
}
所以你可以构建扩展,自定义属性,然后在属性中使用扩展来执行验证逻辑。
再次强调,这只是我已经完成的某些事情。可能不是你要寻找的,但它是一种自定义解决方案。