Как я могу проверить доступность аутентифицированного ресурса, не заставляя браузер запрашивать учетные данные? - PullRequest
0 голосов
/ 14 июля 2020

Я пытаюсь получить данные из веб-службы на другом сервере, но я не знаю заранее, есть ли у пользователя установленный сеанс с этим сервером. Если они это сделают, я хотел бы автоматически получать данные, но если они этого не сделают, я хотел бы провести их через процесс входа в систему, используя свой собственный интерфейс. Чего я хочу избежать, так это показа диалогового окна аутентификации браузера, по крайней мере, до тех пор, пока они не нажмут мою кнопку «Войти».

Существует несколько веб-сервисов, и они используют либо Basi c, либо Negotiate (token / сертификат) auth, смотря какой. Оба типа могут вызвать появление модального / собственного всплывающего окна.

Примечание: я думаю, что мой вопрос в основном этот , за исключением 12 лет спустя. Я попытался добавить заголовок X-Requested-With к запросу, но служба, с которой я говорю, не отбрасывает заголовок WWW-Authenticate в ответ, и я не владею серверной частью, поэтому я не ищу совета, как реализовать этот подход.

1 Ответ

0 голосов
/ 14 июля 2020

Я нашел один подход, который, кажется, работает для определенных случаев использования. Если у защищенной службы также есть способ отправить действительное изображение - возможно, они также защитили страницу «Завершение входа в систему», на которой есть изображения, возможно, они защитили страницу документов Swagger, а не имеет значение - тогда вы можете выполнить тест тега img следующим образом:

// Use a hidden `<img>` tag to test if the provided (protected) resource URL
// can be loaded.  Resolves `true` if the image loads, or `false` if the image
// fails to load.  Rejects if the provided timeout elapses before resolution.
function testAuthWithImage(imgUrl: string, timeoutMS: number): Promise<boolean> {
    return new Promise((resolve, reject) => {
        const canary = document.createElement("img");

        function cleanup() {
            window.clearTimeout(timeout);
            // Must remove event listeners so GC can clean up canary
            canary.removeEventListener("load", loaded);
            canary.removeEventListener("error", failed);
        }

        async function loaded() {
            cleanup();
            resolve(true);
        }

        async function failed() {
            cleanup();
            resolve(false);
        }

        const timeout = window.setTimeout(() => {
            cleanup();
            reject("Connection timed out");
        }, timeoutMS);

        canary.addEventListener("load", loaded);
        canary.addEventListener("error", failed);

        // Assigning ths will cause the image to load or fail
        canary.src = imgUrl;
    });
}

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

    protected async checkLogin(promptForPass: boolean = false): Promise<UserIdentity | undefined> {
        if (await testAuthWithImage(this.TEST_IMG_ENDPOINT.url, this.timeoutMS)) {
            // The image-test worked so we have an existing session; just check the profile.
            try { return await this.fetchUserInfo(); }
            catch (err) {
                // If it was an HttpErrorResponse, throw the `message`
                throw err.message || err;
            }
        } else if (promptForPass) {
            // If the test failed but we're prompting, show user/pass dialog immediately
            return await this.doLogin();
        }
        // If we got here, we're not prompting so return undefined
    }

Я думаю, что он должен постепенно ухудшаться в устаревших браузерах, потому что загрузка субресурса (тег img) вызовет собственное приглашение входа в систему, а затем потерпеть неудачу или добиться успеха в зависимости от того, что с ним делает пользователь. Это не сработает, если сервер еще не предоставил какой-либо подходящий защищенный ресурс, и для этого требуется хотя бы один ложный запрос на рассматриваемое изображение, поэтому я бы приветствовал лучший ответ.

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