Аутентификация, WsFederation & Cookie - пользователь выходит из системы после перезапуска приложения - PullRequest
0 голосов
/ 24 сентября 2018

У меня есть следующее

services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo("keys")).SetApplicationName("Base");

services.AddAuthentication(sharedOptions =>
                    {
                        sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                        sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                        sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
                    })
                    .AddWsFederation(options =>
                    {
                        options.DataProtectionProvider = DataProtectionProvider.Create("Base");
                        options.CallbackPath = "/api/signin-wsfed";
                        options.Events.OnRedirectToIdentityProvider = context =>
                        {
                            var list = context?.Request?.GetTypedHeaders()?.Accept;
                            if (list != null && list.Any(x => x.MediaType.Value.Contains("application/json")))
                            {
                                Log("OnRedirectToIdentityProvider", "Request for URL: '{URL}', Method: '{Method}', Status Code: '{StatusCode}', Old Status Code: '{OldStatusCode}'", context.Request.Path, context.Request.Method, 401, context?.Response?.StatusCode);
                                context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                                context.HandleResponse();
                            }
                            else
                            {
                                Log("OnRedirectToIdentityProvider", "Request for URL: '{URL}', Method: '{Method}', Status Code: '{StatusCode}'", context?.Request?.Path, context?.Request?.Method, context?.Response?.StatusCode);
                            }

                            return Task.CompletedTask;
                        };
                        options.Events.OnAuthenticationFailed = context =>
                        {
                            Log("OnAuthenticationFailed", "Auth Failed: '{Exception}'", context.Exception);

                            return Task.CompletedTask;
                        };

                        options.Events.OnSecurityTokenValidated = context =>
                        {
                            Log("OnSecurityTokenValidated", "Validated for '{User}', Valid '{ValidFrom}' to '{ValidTo}'", context?.Principal?.FindFirst(ClaimTypes.Upn), context?.SecurityToken.ValidFrom, context?.SecurityToken.ValidTo);                      
                            return Task.CompletedTask;
                        };

                        // options.UseTokenLifetime = false;
                        options.Wtrealm = Configuration.GetSection("WsFederation").GetValue<string>("Wtrealm");
                        options.MetadataAddress = Configuration.GetSection("WsFederation").GetValue<string>("MetadataAddress");
                        options.BackchannelHttpHandler = new HttpClientHandler()
                        {
                            ServerCertificateCustomValidationCallback = (_, __, ___, ____) => true
                        };
                    })
                    .AddCookie(options =>
                    {
                        options.DataProtectionProvider = DataProtectionProvider.Create("Base");
                        options.SlidingExpiration = true;

                        // options.ExpireTimeSpan = TimeSpan.FromMinutes(10);
                        options.Events.OnValidatePrincipal += context =>
                        {
                            Log("OnValidatePrincipal", "Validate Cookie for: {User}. Token Issued Utc: '{IssuedUtc}', Token Expires Utc: '{ExpiresUtc}', Cookie Option Valid For: '{CookieOptionValidFor}', Allow Refresh: {AllowRefresh}, ShouldRenew: {ShouldRenew}, Cookie Valid For: '{CookieValidFor}'",
                                context.HttpContext.GetUsername(),
                                context.Properties.IssuedUtc, context.Properties.ExpiresUtc,
                                context.Options.ExpireTimeSpan, context.Properties.AllowRefresh, context.ShouldRenew, context?.Options?.Cookie?.Expiration);

                            return Task.CompletedTask;
                        };

                        options.AccessDeniedPath = null;
                        options.Events.OnRedirectToAccessDenied = context =>
                        {
                            Log("OnRedirectToAccessDenied", "Denied for user: '{User}', For path: '{Url}', Method: '{Method}'", context.HttpContext.GetUsername(), context.Request.Path, context.Request.Method);
                            context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
                            return Task.CompletedTask;
                        };

                        options.Events.OnSignedIn = context =>
                        {
                            var username = context.Principal.FindFirstValue(ClaimTypes.Upn);
                            using (LogContext.PushProperty("User", username))
                            {
                                Log("OnSignedIn", "User '{User}' logged in at: '{At}', Token Expires At: '{Expires}', Sliding Expiration: '{SlidingExpiration}', Cookie Lifetime: '{CookieLifetime}'", 
                                    username, 
                                    DateTimeOffset.Now, 
                                    context.Properties.ExpiresUtc, 
                                    context.Options.SlidingExpiration, 
                                    context.Options.ExpireTimeSpan);
                            }
                            return Task.CompletedTask;
                        };

                        options.Events.OnSigningIn = context =>
                        {

                            context.Properties.AllowRefresh = true;
                            context.CookieOptions.Expires = DateTimeOffset.UtcNow.AddHours(8);

                            return Task.CompletedTask;
                        };
                    });

Каждый раз, когда приложение перезапускается / перезагружается, пользователь перенаправляется на конечную точку adfs, новый токен - receivede, и выдается новый cookie ...

У меня такое ощущение, что я, должно быть, что-то здесь упускаю ... но не уверен, что.

Как видно на всех записях журнала, я много пробовал ...

Сегодня я добавил часть DataProtection ... она не дает сбоя ... приложение работает, как и раньше ...Я не выдаю новую связку ключей в каталоге «keys», поэтому я предполагаю, что она использует эту связку ключей для расшифровки данных.Но это все еще не работает ...

Теперь у меня нет идей, и мне нужна помощь, чтобы понять проблему.

Любые подсказки или идеи, как отладить это, приветствуются ...

Если вам нужна дополнительная информация, пожалуйста, дайте мне знать.

1 Ответ

0 голосов
/ 25 сентября 2018

I'm a / # "() # /" (=! / #) ("= # / Biiiiiip ...

Переопределение options.DataProtectionProvider в Cookie и WsFederation ... MYБОГ.

После удаления этой части, теперь после каждой перезагрузки она работает. Я знаю, что я использую каталог в приложении ... но при развертывании новой версии хорошо, что ключи обновляются, и пользователь долженвойдите снова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...