【问题标题】:ClaimsAuthenticationManager.Authenticate never gets calledClaimsAuthenticationManager.Authenticate 永远不会被调用
【发布时间】:2015-10-15 14:05:57
【问题描述】:

我想在身份验证期间向 Principal 添加一些额外的声明。我正在尝试在使用 Windows 身份验证的 MVC 4.5 项目中实现自定义 ClaimsAuthenticationManager:

namespace Project.Infrastructure
{
    public class ClaimsTransformer : ClaimsAuthenticationManager
    {
        public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
        {
            if (incomingPrincipal != null && incomingPrincipal.Identity.IsAuthenticated == true)
            {
                ((ClaimsIdentity)incomingPrincipal.Identity).AddClaim(new Claim(ClaimTypes.Role, "Admin"));
            }

            return incomingPrincipal;
        }
    }
}

我已将 web.config 设置为使用我的自定义类:

<configSections>
    <section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
</configSections>

<system.identityModel>
    <identityConfiguration>
      <claimsAuthenticationManager type="Project.Infrastructure.ClaimsTransformer, [AssemblyName]" />
    </identityConfiguration>
</system.identityModel>

但是 Authenticate 方法永远不会被调用。我错过了什么吗?

【问题讨论】:

  • 您是否已将索赔授权模块添加到您的 .config 中?
  • 不,我没有自定义授权。我的理解是两者是分开的和不同的,一个不依赖于另一个。这不正确吗?

标签: c# asp.net-mvc asp.net-mvc-4 wif claims-based-identity


【解决方案1】:

缺少的步骤是您需要添加一个 HTTP 模块来启动所有这些。

所以,你需要一个如下所示的类:

public class MyClaimsAuthenticationModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.PostAuthenticateRequest += Context_PostAuthenticateRequest;
    }

    public void Dispose()
    {
        // Nothing to dispose, method required by IHttpModule
    }

    void Context_PostAuthenticateRequest(object sender, EventArgs e)
    {
        var transformer = FederatedAuthentication.FederationConfiguration.IdentityConfiguration.ClaimsAuthenticationManager;
        if (transformer != null)
        {
            var context = ((HttpApplication)sender).Context;
            var principal = context.User as ClaimsPrincipal;
            var transformedPrincipal = transformer.Authenticate(context.Request.RawUrl, principal);

            context.User = transformedPrincipal;
            Thread.CurrentPrincipal = transformedPrincipal;
        }
    }
}

这将获取您在 web.config 中指定的转换器并对其调用身份验证,然后将返回的主体附加到 HttpContext 和当前线程。

您的 web.config 中还需要类似以下内容:

<system.webServer>
  <modules>
    <add name="MyClaimsAuthenticationModule" type="MyApplication.MyHttpModels.MyClaimsAuthenticationModule, MyApplicationAssembly" />
  </modules>
</system.webServer>

更新

当然,您可以将Context_PostAuthenticationRequest 方法中的代码放入PostAuthenticateRequest 处理程序的Global.asax.cs 类文件中。但是,我更喜欢将类的职责保持在较小的范围内,因此我选择了 IHttpModule 的实现,以便模块完成它的工作,并且很明显它是什么,并且它与可能在各种情况下发生的其他事情分开管道的各个阶段。

如果您的 Global.asax.cs 文件很小,那么将代码放在那里没有问题。它应该仍然有效。但是,您在课堂上混合了职责,将来可能会变得笨拙。

【讨论】:

  • MSDN 不清楚 ClaimsAuthenticationManager 不会被调用以进行 Windows 身份验证,并且必须手动连接。谢谢...正是我想要的。如果我已经有一个 global.asax 文件,我是否也可以在 Application_PostAuthenticateRequest 方法中执行连线?
  • 是的,我想你可以。我个人不喜欢这样做,我更喜欢将事物放在实现 IHttpModule 的类中以保持关注点分开。 (即这个模块做一件事)如果你的 Global asax 很小并且会保持很小,那么我认为将代码放在那里没有问题。显然,如果它变得更大,那是因为它做的事情太多了。所以,你真的需要考虑拆分不同的职责。
  • 我们为什么需要绕道 System.IdentityModel.ClaimsAuthenticationManager 呢? - 我的意思是,我为什么不能把自定义ClaimsTransformer的代码直接放到MyClaimsAuthenticationModule中?
  • 对我来说最重要的原因是单一职责原则。该模块的目的是为 ASP.NET HTTP 管道提供一个挂钩,声明转换器的目的是生成/转换将添加到管道中的声明主体。
【解决方案2】:

您是否使用类似的方法调用 Authenticate 方法,但没有进行身份验证?

ClaimsTransformer manager = new ClaimsTransformer();
manager.Authenticate("resource", incomingPrincipal )

您可能希望将 ClaimsTransformer 类中的“返回incomingPrincipal”替换为调用:

return base.Authenticate(resourceName, incomingPrincipal);

还有为什么需要 Windows 身份验证?

【讨论】:

  • base.Authentication 方法什么都不做。字面意思是:public virtual ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal) { return incomingPrincipal; }
猜你喜欢
  • 2012-10-27
  • 2013-10-12
  • 2012-03-27
  • 2013-08-29
  • 2013-11-03
  • 1970-01-01
  • 1970-01-01
  • 2015-05-06
  • 1970-01-01
相关资源
最近更新 更多