ClaimsAuthenticationManager.永远不会调用Authenticate

本文关键字:调用 Authenticate 永远 ClaimsAuthenticationManager | 更新日期: 2023-09-27 18:04:37

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

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;
        }
    }
}

我有网。设置为使用我的自定义类:

<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方法永远不会被调用。我错过什么了吗?

ClaimsAuthenticationManager.永远不会调用Authenticate

您需要添加一个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中指定的转换器。配置并在其上调用authenticate,然后将返回的主体附加到HttpContext和当前线程。

你还需要在你的web.config中设置如下内容:

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

当然,您可以将Context_PostAuthenticationRequest方法中的代码放在Global.asax.cs类文件中的PostAuthenticateRequest处理程序中。然而,我更喜欢保持类的责任小,所以我去IHttpModule的实现,使模块做它的事情,这是很明显的,它是分开的其他事情可能发生在管道的各个阶段。

如果你的Global.asax.cs文件很小,那么把代码放在那里是没有问题的。它应该还能用。但是,您在类中混合了职责,将来可能会变得难以处理。

您是否使用类似的东西调用Authenticate方法,而身份验证没有发生?

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

你可能想要将ClaimsTransformer类中的"return incomingPrincipal"替换为调用:

return base.Authenticate(resourceName, incomingPrincipal);

为什么你需要Windows认证?