Как установить общий Wreply для нескольких конечных точек ADFS с OWIN? - PullRequest
1 голос
/ 18 апреля 2019

Я хочу настроить конечные точки ADFS в моем приложении asp.net во время выполнения. Существует проблема: если я объявляю один метод обратного вызова для нескольких конечных точек, то у меня есть исключение:

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

Логин и общий обратный вызов (Wreply) в 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");
        }

Я прочитал много ответов по настройке жестко запрограммированных нескольких конечных точек ADFS в Web.config, но есть ли возможность настроить точки во время выполнения?

Спасибо!

1 Ответ

0 голосов
/ 10 июля 2019

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