Непоследовательное поведение от встроенной проверки подлинности Windows на Chrome и IE - PullRequest
0 голосов
/ 14 марта 2019

Я сталкиваюсь со странной проблемой, связанной с интегрированной аутентификацией Windows на веб-сайте SPA (интрасеть)

Процесс входа в систему выглядит следующим образом:

  • Клиент переходит на сайт SPA
  • во время инициализации SPA, SPA отправляет запрос к конечной точке токена из моего WEB API, там я извлекаю учетные данные AD, выполняю поиск в БД и добавляю некоторые заявки на роль
  • Конечная точка токена возвращает токен, действительный в течение пары часов
  • SPA использует токен во всех последующих HTTP-запросах
  • Когда срок действия токена истекает (за 10 секунд до этого), SPA снова делает точно такой же запрос токена, запрос поступает в мой код OAuthAuthorizationServerProvider, , но иногда context.OwinContext.Request.User.Identity имеет значение null что-то пошло не так, передавая учетные данные AD
  • у конечного пользователя больше нет действующего токена, и он не может выполнять какие-либо вызовы http, обновление страницы устраняет проблему, точно такой же запрос токена выполняется и работает каждый раз

Некоторые замечания:

  • эта проблема присутствует как в IE, так и в Chrome, хотя IE имеет тенденцию к меньшему количеству всплесков, хотя
  • Веб-сервер - IIS 7.5, включена только аутентификация Windows, только в качестве провайдера - только NTLM

Клиент (я использую fetch для всего остального, я переписал это классическим способом устранения возможных помех, но безрезультатно):

public async logIn(): Promise<boolean> {
    return new Promise(function (resolve, reject) {

        var http = new XMLHttpRequest();
        var url = `${environment.baseUrl}/token`;
        var params = 'grant_type=password&username=&password=';
        http.open('POST', url, true);
        http.withCredentials = true;

        //Send the proper header information along with the request
        http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

        http.onreadystatechange = () => {
            if (http.readyState == 4 && http.status == 200) {
                let result = JSON.parse(http.responseText);
                alert(http.responseText);

                if (result.access_token) {
                    localStorage.setItem(EMPLOYEEID, result.employeeId);
                    localStorage.setItem(ROLES, result.roles);
                    localStorage.setItem(TOKEN, result.access_token);
                    localStorage.setItem(
                        TOKENEXPIRY,
                        moment()
                            .add(result.expires_in, "seconds")
                            .toJSON()
                    );
                    return resolve(true);
                } else return resolve(false);
            }
        }
        http.send(params);
    })
}

public enableSilentTokenRenew() {
    setTimeout(async () => {
        await this.logIn(); //this fails
        this.enableSilentTokenRenew();
    }, moment(localStorage.getItem(TOKENEXPIRY)).diff(moment(), "millisecond") - 10000);
}

Сервер:

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        var adUser = context.OwinContext.Request.User.Identity // this is null the second time
...