C# 为什么未调用ClaimsAuthorizationManager.LoadCustomConfiguration?
我正在尝试实现我自己的C# 为什么未调用ClaimsAuthorizationManager.LoadCustomConfiguration?,c#,configuration,authorization,claims-based-identity,claims,C#,Configuration,Authorization,Claims Based Identity,Claims,我正在尝试实现我自己的ClaimsAuthorizationManager,主要遵循MSDN上的示例。目标是从项目配置文件加载策略,并使用它们评估应用程序发出的访问控制请求 我的自定义ClaimsAuthorizationManager与下面的代码非常相似 当我运行TestSuite来测试CheckAccess()方法时,它失败了。我调试并注意到管理器没有从配置文件加载策略事实上,LoadCustomConfiguration()方法从未被调用,即使我在配置中注册了自定义管理器。这是什么原因 我
ClaimsAuthorizationManager
,主要遵循MSDN上的示例。目标是从项目配置文件加载策略,并使用它们评估应用程序发出的访问控制请求
我的自定义ClaimsAuthorizationManager
与下面的代码非常相似
当我运行TestSuite来测试CheckAccess()
方法时,它失败了。我调试并注意到管理器没有从配置文件加载策略事实上,LoadCustomConfiguration()
方法从未被调用,即使我在配置中注册了自定义管理器。这是什么原因
我正试图在一个TestProject中对此进行测试,其中我的App.config如下所示:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!--WIF 4.5 sections -->
<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
</configSections>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" /></startup>
<system.identityModel>
<identityConfiguration>
<claimsAuthorizationManager type="Foo.Bar.ClaimsAuthorization.FooBarAuthorizationManager, Foo.Bar.ClaimsAuthorization">
<policy resource="TestResource" action="TestAction">
<or>
<claim claimType="http://schemas.microsoft.com/ws/2008/06/identity/claims/role" claimValue="Developer" />
<claim claimType="http://schemas.xmlsoap.org/claims/Group" claimValue="Administrator" />
</or>
</policy>
</claimsAuthorizationManager>
</identityConfiguration>
</system.identityModel>
</configuration>
var hasAccess = ClaimsAuthorization.CheckAccess("TestAction", "TestResource");
Assert.IsFalse(hasAccess);
我意识到我的设置是正确的,但我以错误的方式调用了自定义
ClaimsAuthorizationManager
因为我自己(错误地)初始化了AuthorizationManager,而不是使用系统基于配置创建的AuthorizationManager,所以我绕过了整个“LoadCustomConfiguration()”部分
解决方案是调用系统在启动时创建的ClaimsAuthorizationManager。
我真的不知道如何从TestSuite环境(即不是从ASP.NET)正确调用它,但我发现了这个有用的包,它可以轻松访问当前有效的ClaimsAuthorizationManager:
namespace Foo.Bar.ClaimsAuthorization
{
public class FooBarAuthorizationManager : ClaimsAuthorizationManager
{
static readonly Dictionary<ResourceAction, Func<ClaimsPrincipal, bool>> Policies = new Dictionary<ResourceAction, Func<ClaimsPrincipal, bool>>();
readonly PolicyReader policyReader = new PolicyReader();
/// <summary>
/// Overloads the base class method to load the custom policies from the config file
/// </summary>
/// <param name="nodelist">XmlNodeList containing the policy information read from the config file</param>
public override void LoadCustomConfiguration(XmlNodeList nodelist)
{
if (nodelist == null)
return;
foreach (XmlNode node in nodelist)
{
//
// Initialize the policy cache
//
XmlDictionaryReader rdr = XmlDictionaryReader.CreateDictionaryReader(new XmlTextReader(new StringReader(node.OuterXml)));
rdr.MoveToContent();
string resource = rdr.GetAttribute("resource");
string action = rdr.GetAttribute("action");
Expression<Func<ClaimsPrincipal, bool>> policyExpression = policyReader.ReadPolicy(rdr);
//
// Compile the policy expression into a function
//
Func<ClaimsPrincipal, bool> policy = policyExpression.Compile();
//
// Insert the policy function into the policy cache
//
Policies[new ResourceAction(resource, action)] = policy;
}
}
/// <summary>
/// Checks if the principal specified in the authorization context is authorized to perform action specified in the authorization context
/// on the specified resoure
/// </summary>
/// <param name="pec">Authorization context</param>
/// <returns>true if authorized, false otherwise</returns>
public override bool CheckAccess(AuthorizationContext pec)
{
//
// Evaluate the policy against the claims of the
// principal to determine access
//
bool access;
try
{
var ra = new ResourceAction(pec.Resource.First().Value, pec.Action.First().Value);
access = Policies[ra](pec.Principal);
}
catch (Exception)
{
access = false;
}
return access;
}
public bool CheckAccess(string resource, string action)
{
return CheckAccess(resource, action, Thread.CurrentPrincipal);
}
public bool CheckAccess(string resource, string action, IPrincipal principal)
{
var claimsPrincipal = principal as ClaimsPrincipal;
if (claimsPrincipal == null)
throw new ArgumentException("Principal is null or not of type ClaimsPrincipal!", "principal");
var context = new AuthorizationContext(claimsPrincipal, resource, action);
return CheckAccess(context);
}
}
}
现在我可以简单地这样称呼它:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!--WIF 4.5 sections -->
<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
</configSections>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" /></startup>
<system.identityModel>
<identityConfiguration>
<claimsAuthorizationManager type="Foo.Bar.ClaimsAuthorization.FooBarAuthorizationManager, Foo.Bar.ClaimsAuthorization">
<policy resource="TestResource" action="TestAction">
<or>
<claim claimType="http://schemas.microsoft.com/ws/2008/06/identity/claims/role" claimValue="Developer" />
<claim claimType="http://schemas.xmlsoap.org/claims/Group" claimValue="Administrator" />
</or>
</policy>
</claimsAuthorizationManager>
</identityConfiguration>
</system.identityModel>
</configuration>
var hasAccess = ClaimsAuthorization.CheckAccess("TestAction", "TestResource");
Assert.IsFalse(hasAccess);
更新:反编译源代码显示,这是
FederatedAuthentication.FederationConfiguration.IdentityConfiguration.ClaimsAuthorizationManager
这似乎是访问当前的
ClaimsAuthorizationManager
Doh的正确方法,我刚刚意识到我可能不应该自己创建authManager。我不知道如何调用CheckAccess。我正在尝试构建您上面提供的代码。您能告诉我在哪个命名空间中找到“PolicyReader”类吗?我尝试过在MSDN上搜索,但唯一的参考是一个密封的嵌套类。它在中,这里是直接下载链接:对我来说,使用注册的ClaimsAuthorizationManager的这种方式也很有效:ClaimsPrincipalPermission.CheckAccess(“TestResource”,“TestAction”)代码>