如何使用 OWIN 为多个 ADFS 端点设置通用 Wreply?

How to set common Wreply for multiple ADFS endpoints with OWIN?

我想在运行时在我的 asp.net 应用程序中配置 ADFS 端点。 有一个问题:如果我为多个端点声明单个回调方法,那么我有异常:

Microsoft.IdentityModel.Tokens.SecurityTokenSignatureKeyNotFoundException: IDX10501: Signature validation failed. Unable to match keys: 
kid: '[PII is hidden]', 
token: '[PII is hidden]'.

如果我将为每个端点硬编码回调 (Wreply),那么一切正常,但这不是我的情况。

Startup.cs

 public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            var federationEndpoints = Service.ListActiveFederationEndpoints();
            if (federationEndpoints.Any())
            {
                app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
                app.UseCookieAuthentication(new CookieAuthenticationOptions());

                var endpointOptions = new List<WsFederationAuthenticationOptions>();
                foreach (var endpoint in federationEndpoints)
                {
                    string metadata = endpoint.ServerUri;
                    string wtrealm = endpoint.RelyingPartyIdentifier;

                    endpointOptions.Add(new WsFederationAuthenticationOptions
                    {
                        Wtrealm = wtrealm,
                        MetadataAddress = metadata,
                        AuthenticationType = endpoint.Name
                    });
                }
                app.Map("/FederationAuth", configuration =>
                {
                    endpointOptions.ForEach(o => app.UseWsFederationAuthentication(o));
                });
            }
            AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Name;
        }
    }

FederationAuthController 中的登录和公共回调(Wreply)

        [AllowAnonymous]
        public void ExternalLogin(string endpointName)
        {
            var ctx = Request.GetOwinContext();
            ctx.Authentication.Challenge(
                new AuthenticationProperties { RedirectUri = Url.Action("LoginCallbackAdfs", "FederationAuth") },
                endpointName);
        }

        public ActionResult LoginCallbackAdfs()
        {
            var ctx = System.Web.HttpContext.Current;
            var claimsIdentity = User.Identity as ClaimsIdentity;
            var sessionIdentity = Service.LoginByClaims(claimsIdentity);
            return this.RedirectToAction("Index", "SinglePage");
        }

我在 Web.config 中阅读了很多关于配置硬编码多个 ADFS 端点的答案,但是是否有可能在运行时配置 enpoints?

谢谢!

Wreply 应该是唯一的,并在管道构建期间为每个联合中间件设置。我制作了独特的 Wreply,包括端点名称作为回调参数。 Startup.cs

    public void Configuration(IAppBuilder app)
    {          
             var federationChannels = Service.GetFederationChannels();    
             app.UseCookieAuthentication(new CookieAuthenticationOptions());
             app.SetDefaultSignInAsAuthenticationType(CookieAuth.AuthenticationType);
             foreach (var channel in federationChannels)
             {
                var metadata = channel.Metadata;
                var wtrealm = channel.Wtrealm ;
                var host = GetServerAddress();
                var wreply = $"{host}FederationLogin/channel={channel.Id}";

                app.UseWsFederationAuthentication(new WsFederationAuthenticationOptions
                {
                    Wtrealm = wtrealm,
                    MetadataAddress = metadata,
                    AuthenticationType = channel.Id,
                    Wreply = wreply,
                    SignOutWreply = host
                });
            }          
            AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Name;         
    }

控制器

public ActionResult FederationLogin(string channel)
{
....
    HttpContext.GetOwinContext().Authentication.Challenge(new AuthenticationProperties(), channel);
....
}