【发布时间】:2015-12-21 23:29:59
【问题描述】:
我有一个 ASP.NET MVC 5 应用程序,我正在努力获得索赔授权。我读过一堆总是在 web.config 文件中设置 ClaimsAuthorizationManager 类的东西。
是否可以在代码中设置自定义ClaimsAuthorizationManager?
【问题讨论】:
标签: asp.net-mvc wif claims-based-identity
我有一个 ASP.NET MVC 5 应用程序,我正在努力获得索赔授权。我读过一堆总是在 web.config 文件中设置 ClaimsAuthorizationManager 类的东西。
是否可以在代码中设置自定义ClaimsAuthorizationManager?
【问题讨论】:
标签: asp.net-mvc wif claims-based-identity
我正在回答我自己的问题。在我的 global.asax 文件的 ApplicationStart 方法中,使用以下代码:
System.IdentityModel.Services.FederatedAuthentication.FederationConfigurationCreated += (s, e) =>
{
e.FederationConfiguration.IdentityConfiguration.ClaimsAuthorizationManager = new MyCustomClaimsAuthorizationManager();
};
【讨论】:
也许对答案的这种轻微阐述可以帮助其他人,因为我刚刚在 MVC 5、.NET 4.5.2 中经历了一些非常相似的事情,并发现有必要了解这些组件在幕后的行为方式。
我的主要目标:需要最小化 .config 依赖(ffwd:在我有空的时候,我找到了最小化但没有完全删除的方法)
我在使用此答案的方法时遇到的问题是我不断收到错误消息,说我缺少配置内容。经过一些好的旧反射器反射后,我发现这是由 mish-mosh、静态 getter 菊花链、实例构造和 FederatedAuthentication、FederationConfiguation 和 IdentityConfigution 类之间的成员初始化引起的。
首先,FederatedAuthentication 类的 FederationConfiguration getter 属性惰性初始化底层的“FederationConfiguration”字段。
public static FederationConfiguration FederationConfiguration
{
get
{
if (_federationConfiguration == null)
{
object federationConfigurationLock = FederationConfigurationLock;
lock (federationConfigurationLock)
{
if (_federationConfiguration == null)
{
_federationConfiguration = CreateFederationConfiguration();
}
}
}
return _federationConfiguration;
}
}
总结初始化例程:
FederatedConfiguration默认ctor(调用: this(true),但我跑题了)如果尚未初始化,则启动初始化链
private static FederationConfiguration CreateFederationConfiguration()
{
System.IdentityModel.Services.Configuration.FederationConfiguration federationConfiguration = new System.IdentityModel.Services.Configuration.FederationConfiguration();
federationConfiguration = OnFederationConfigurationCreated(federationConfiguration);
if (federationConfiguration.IsAmbiguous)
{
throw DiagnosticUtil.ExceptionUtil.ThrowHelperError(new ConfigurationErrorsException(System.IdentityModel.Services.SR.GetString("ID7018")));
}
if (!federationConfiguration.IsInitialized)
{
federationConfiguration.Initialize();
}
return federationConfiguration;
}
}
了解此例程很重要,因为(至少对我而言)表面上并不明显,如果您确实参与了该活动并尝试做一些预订外的事情,您需要知道拨打@987654330 @ 和/或 IdentityConfig 类的 Initialize() 方法,以潜在地避免一些在其他情况下为您调用时发生的副作用。
有一种“如果未初始化,则调用Initialize”的模式沿着对象链运行,并且由于实现,这些类上的IsInitialized 属性只能设置为返回true,如果它们Initialize() 方法成功完成。
我能够设置我的自定义 ConfigurationManager 并避免由于 .config 依赖而导致的一些错误的方法是让我的事件处理程序足够聪明,可以抢先调用 IdentityConfiguration 对象上的 Initialize() 方法 - 这实际上改变了框架的 IdentityModel 类中的执行路径。
var authZ = new MyClaimsAuthorizationManager();
FederatedAuthentication.FederationConfigurationCreated += (s, e) =>
{
var identityConfiguration = e.FederationConfiguration.IdentityConfiguration;
identityConfiguration.ClaimsAuthorizationManager = authZ;
if (!identityConfiguration.IsInitialized)
identityConfiguration.Initialize();
};
}
有一些博客/SO 答案谈到了如何以编程方式设置它,所有这些都有简单的 loc:e.FederationConfiguration.IdentityConfiguration.ClaimsAuthorizationManager = new MyCustomClaimsAuthorizationManager(); 在事件处理程序中;对我来说不幸的是,这还不够,因为我正在努力完成。希望这可以帮助其他“简单答案”还不够的人。
【讨论】:
你应该可以通过ServiceConfiguration类来设置它:
ServiceConfiguration.ClaimsAuthorizationManager = new MyClaimsAuthManager();
【讨论】: