Переходный бесконечный цикл входа в службу приложений Azure - OpenIDConnect Auth с Azure AD - PullRequest
0 голосов
/ 15 января 2019

Фон

Итак, у нас есть служба приложений, которая аутентифицируется из Azure AD в другом клиенте с использованием OpenIdConnect.

Вход в систему работает на экземпляре IIS разработчика, а также на нашем сервисе тестового приложения. Мы увидели проблему в тесте, и она исчезла и не возвращалась в течение всей фазы тестирования проекта.

Теперь мы развернуты в производство и снова видим проблему.

Выпуск

То, что мы видим, это то, что в течение некоторого времени все будет работать нормально, а затем через несколько часов проблема снова возникнет.

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

Код

public void ConfigureAuth(IAppBuilder app)
        {
            //Azure AD Configuration
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
            app.UseCookieAuthentication(new CookieAuthenticationOptions());


            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {
                    //sets client ID, authority, and RedirectUri as obtained from web config
                    ClientId = clientId,
                    ClientSecret = appKey,
                    Authority = authority,
                    RedirectUri = redirectUrl,

                    CallbackPath = new PathString("/"), //use this line for production and test


                    //page that users are redirected to on logout
                    PostLogoutRedirectUri = redirectUrl,

                    //scope - the claims that the app will make
                    Scope = OpenIdConnectScope.OpenIdProfile,
                    ResponseType = OpenIdConnectResponseType.CodeIdToken,

                    //setup multi-tennant support here, or set ValidateIssuer = true to config for single tennancy
                    TokenValidationParameters = new TokenValidationParameters()
                    {
                        ValidateIssuer = true,
                        //SaveSigninToken = true
                    },
                    Notifications = new OpenIdConnectAuthenticationNotifications
                    {
                        AuthenticationFailed = OnAuthenticationFailed,
                        AuthorizationCodeReceived = OnAuthorizationCodeReceived,
                    }
                }
                );
        }

        private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedNotification context)
        {
            var code = context.Code;
            ClientCredential cred = new ClientCredential(clientId, appKey);
            string userObjectId = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
            //this token cache is stateful, we're going to populate it here, but we'll store it elsewhere in-case the user ends up accessing a different instance
            AuthenticationContext authContext = new AuthenticationContext(authority, new NaiveSessionCache(userObjectId));

            // If you create the redirectUri this way, it will contain a trailing slash.  
            // Make sure you've registered the same exact Uri in the Azure Portal (including the slash).
            Uri uri = new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path));
            AuthenticationResult result = await authContext.AcquireTokenByAuthorizationCodeAsync(code, uri, cred, "https://graph.windows.net");

            //populate the persistent token cache
            testdb2Entities5 db = new testdb2Entities5();
            PersistentTokenCache tc = await db.PersistentTokenCaches.FindAsync(userObjectId);
            //if null, populate a new item
            if (tc == null)
            {
                tc = new PersistentTokenCache();
                tc.object_id = userObjectId;
                tc.token = code;
                db.PersistentTokenCaches.Add(tc);
                await db.SaveChangesAsync();

            }
            else
            {
                tc.token = code;
                await db.SaveChangesAsync();
            }

        }

        //authentication failed notifications
        private Task OnAuthenticationFailed(AuthenticationFailedNotification<Microsoft.IdentityModel.Protocols
                                                                            .OpenIdConnect.OpenIdConnectMessage,
                                                                            OpenIdConnectAuthenticationOptions> context)
        {
            context.HandleResponse();
            context.Response.Redirect("/?errormessage=" + context.Exception.Message);
            return Task.FromResult(0);
        }

Вопрос

Итак, основываясь на том, что делает включение и отключение аутентификации службы приложений, оно явно исправляет ситуацию временно. Так что я думаю, что это проблема, связанная с cookie - поскольку это было бы единственной вещью, передающей состояние между сеансами. Что на земле может быть проблема здесь? И какие шаги мне нужно предпринять, чтобы диагностировать и решить проблему?

1 Ответ

0 голосов
/ 16 января 2019

Пока что кажется, что это была проблема с известной ошибкой в ​​Katana, когда менеджер cookie Katana и менеджер cookie ASP .NET конфликтуют и перезаписывают файлы cookie друг друга.

Вот некоторые неисправности, к которым вы могли бы обратиться:

1.ЗАГРУЗКА app.UseCookieAuthentication(new CookieAuthenticationOptions {CookieSecure == CookieSecureOption.Always}). Это означает, что cookie может просочиться вместе с вашей аутентификацией.

2.Добавьте SystemWebCookieManager в UseCookieAuthentication, который находится в Microsoft.Owin.Host.SystemWeb пакете Nuget. Пожалуйста, обратитесь к этой теме .

3. Разделенное печенье . Кто-то заметил, что проблема в том, что количество символов Cookie превышает ограничение браузера (> 4096). Таким образом, чтобы преодолеть эту проблему, в set-cookie, содержащем около 4000 символов каждый, и при необходимости объедините все cookie вместе, чтобы получить исходное значение.

Подробнее о том, как добавить вход с помощью Microsoft в веб-приложение ASP.NET, см. В этой статье .

Update :

Исправлено с установкой Kentor.OwinCookieSaver пакета nuget и добавлением app.UseKentorOwinCookieSaver(); до app.UseCookieAuthentication(new CookieAuthenticationOptions());

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