Я пытаюсь использовать ws-federation с ядром .net для обработки единого входа. Мне удалось получить токен безопасности от моей федеративной службы, но утверждения, полученные из токена безопасности, не добавляются к пользователю, который проходит аутентификацию, и даже несмотря на то, что файл cookie записывается после проверки токена, пользователь не получает обновленный набор удостоверений или утверждений, оставляя пользователя в состоянии, в котором HttpContext.User.Identity.IsAuthenticated всегда имеет значение false.

Мои настройки сервисов:

public void ConfigureServices(IServiceCollection services)
        {
            IdentityModelEventSource.ShowPII = true;
            services.AddControllersWithViews();


            services.AddAuthentication(sharedOptions =>
            {
                sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
                sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            }
            ).AddWsFederation(options =>
            {
                WsFederationConfiguration configuration = new WsFederationConfiguration();
                configuration.Issuer = "http://localhost/STSSpike2/V1";
                configuration.TokenEndpoint = "http://localhost/STSSpike/V1";
                options.Configuration = configuration;
                options.Wtrealm = "http://localhost/STSAwareApp/Test";
                options.Wreply = "http://localhost/STSAwareApp/signin-wsfed";
                options.SecurityTokenHandlers.Add(new FakeTokenValidator());

                options.Events.OnAuthenticationFailed = context =>
                {
                    Console.WriteLine(context.Exception.ToString());
                    return Task.CompletedTask;
                };

                options.Events.OnAccessDenied = context =>
                {
                    Console.WriteLine(context);
                    return Task.CompletedTask;
                };

                options.Events.OnRemoteFailure = context =>
                {
                    Console.WriteLine(context.Failure);
                    return Task.CompletedTask;
                };

                options.Events.OnSecurityTokenReceived = context =>
                {
                    Console.WriteLine(context.ProtocolMessage);
                    return Task.CompletedTask;
                };

                options.Events.OnSecurityTokenValidated = context =>
                {
                    Console.WriteLine(context);
                    return Task.CompletedTask;
                };

            }).AddCookie(options =>
            {
                options.Cookie.Name = "TestStsAuth1";
                options.ExpireTimeSpan = new TimeSpan(0, 30, 0);
                options.Cookie.IsEssential = true;
                //options.Cookie.HttpOnly = true;
                options.Cookie.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None;
                options.Events = new CookieAuthenticationEvents
                {
                    OnValidatePrincipal = val =>
                    {
                        Console.WriteLine("validated");
                        return Task.CompletedTask;
                    },
                    OnRedirectToAccessDenied = denied =>
                    {
                        Console.WriteLine("validated");
                        return Task.CompletedTask;
                    },
                    OnRedirectToReturnUrl = redirect =>
                    {
                        Console.WriteLine("validated");
                        return Task.CompletedTask;
                    },
                    OnSignedIn = signedIn =>
                    {
                        Console.WriteLine("Signedin");
                        return Task.CompletedTask;
                    },
                    OnSigningIn = signingIn =>
                    {
                        Console.WriteLine("signing in");
                        return Task.CompletedTask;
                    }
                };
            });

            services.AddLogging(
                builder =>
                {
                builder.AddFilter("Microsoft", LogLevel.Trace)
                       .AddFilter("System", LogLevel.Trace)
                       .AddConsole();
                });
        }

В приведенном выше коде Events.OnSecurityTokenValidated и CookieOptions.Events.OnSignedIn указывают на участника, полученного из токена безопасности, возвращенного из ws-federation. Однако HttpContext.User никогда не обновляется новым удостоверением. Поэтому, как только токен безопасности проверен, клиент повторно обращается к федеративному серверу, чтобы запросить токен, с единственными сообщениями журнала: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Информация: Ошибка авторизации.

1
bogertron 23 Апр 2020 в 03:00

1 ответ

Проблема возникла из-за моего вызова Configure в том, что я вызвал UseAuthorization перед вызовом UseAuthentication. Этот ответ был ключом к выяснению проблемы.

1
bogertron 23 Апр 2020 в 20:59