如何在运行时使用OWIN配置多个ADFS端点?

时间:2019-04-18 08:58:46

标签: owin adfs

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

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

如果我要对每个端点的回调进行硬编码,那么所有方法都可以工作,但这不是我的情况。

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中的登录和常见回调

        [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终结点的答案,但是是否有可能在运行时配置points?

谢谢!

1 个答案:

答案 0 :(得分:0)

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