Подтвердить что ты не робот

Oauth2 Implicit Flow с токенами для обновления одного страницы-приложения

Я использую Thinktecture AuthorizationServer (AS), и он отлично работает.

Я хотел бы написать собственное одностраничное приложение javascript, которое может вызывать WebAPI напрямую, однако неявный поток не предоставляет токен обновления.

Если вызов AJAX сделан, если токен истек, API отправит перенаправление на страницу входа, так как данные используют динамические всплывающие окна, это приведет к прерыванию пользователя.

Как Facebook или Stackoverflow делают это и все еще разрешают запуск javascript на странице для вызова API?

Предлагаемое решение

Является ли приведенный ниже сценарий разумным (если это можно сделать с помощью iframes):

Мой SPA направляет меня в AS, и я получаю токен от Implicit Flow. В пределах AS я нажимаю разрешать область Read data и нажимаю Remember decision, затем Allow.

Так как я нажал кнопку Remember decision, всякий раз, когда я нажимаю AS для токена, новый токен автоматически возвращается без необходимости входа в систему (я могу видеть файл cookie FedAuth, который помнит мое решение и полагает, что это позволяет это просто работать).

С моим SPA (ненадежным приложением) у меня нет токена обновления только токена доступа. Поэтому вместо этого я:

  • Убедитесь, что пользователь вошел в систему и нажал кнопку "запомнить" (иначе iframe не будет работать)
  • Вызовите WebAPI, если ответ 401 попробует и получит новый токен с помощью следующих шагов...
  • У вас есть скрытый iframe на странице, который я установил для URL-адреса, чтобы получить новый токен доступа с сервера авторизации.
  • Получить новый токен из хэш-фрагмента iframe, затем сохранить его в SPA и использовать для всех будущих запросов WebAPI.

Я думаю, у меня все еще будет неприятность, если файл cookie FedAuth будет украден.

Любой стандартный или рекомендуемый способ для вышеуказанного сценария?

4b9b3361

Ответ 1

В Google o-Auth токен доступа будет действителен только в течение 1 часа, поэтому вам необходимо программно обновить токен доступа в течение одного часа, просто вы можете создать веб-api для этого, вам нужно обновить токен, а также то, что токен обновления не истек, используя код С#, я сделал это.

 if (dateTimeDiff > 55)
            {
                var request = (HttpWebRequest)WebRequest.Create("https://www.googleapis.com/oauth2/v3/token");
                var postData = "refresh_token=your refresh token";
                postData += "&client_id=your client id";
                postData += "&client_secret=your client secrent";
                postData += "&grant_type=refresh_token";

                var data = Encoding.ASCII.GetBytes(postData);            
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
                request.ContentLength = data.Length;
                request.UseDefaultCredentials = true;

                using (var stream = request.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }
                var response = (HttpWebResponse)request.GetResponse();
                string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();

            }

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

Ответ 2

Похоже, вам нужно заказывать запросы в случае истечения токена доступа. Это более или менее то, как Facebook и Google это делают. Простым способом использования Angular было бы добавить HTTP-перехватчик и проверить ответы HTTP401. Если кто-то возвращается, вы повторно аутентифицируете и ставите в очередь все запросы, которые появляются после завершения запроса на аутентификацию (то есть обещание). После этого вы можете обработать оставшуюся очередь с помощью вновь полученного маркера доступа из вашего запроса на аутентификацию, используя токен обновления.

Счастливое кодирование.

Ответ 3

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

Как я уверен, вы уже знаете, неявный грант должен использоваться потребителями, которые НЕ могут хранить свои учетные данные в тайне. Из-за этого токен доступа, который выдается сервером авторизации, должен иметь ограниченный ttl. Например, google делает недействительным свой токен доступа в 3600 сек. Конечно, вы можете увеличить ttl, но он никогда не должен становиться долгоживущим токеном.

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

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

Ответ 4

Не уверен, что я понимаю ваш вопрос, но

Я хотел бы написать собственное одностраничное приложение javascript, которое может вызывать WebAPI напрямую, однако неявный поток не предоставляет токен обновления.

Подведите итоги,

токен обновления иногда используется как часть A: Разрешение авторизации

https://tools.ietf.org/html/rfc6749#section-1.5

и, как вы сказали в неявном потоке, вы не возвращаете токен обновления, а только в разделе "Разрешить авторизацию"

https://tools.ietf.org/html/rfc6749#section-4.2.2

чтобы вы могли вернуть токен обновления при выдаче токена доступа (обновлять токены всегда необязательно)

https://tools.ietf.org/html/rfc6749#section-5.1

С моим SPA (ненадежным приложением) у меня нет токена обновления только токен доступа. Поэтому вместо этого я:

1) Убедитесь, что пользователь вошел в систему и нажал кнопку "запомнить" (в противном случае iframe не работает)

2) Вызовите WebAPI, если ответ 401 попробует и получит новый токена с помощью следующих шагов...

3) У вас есть скрытый iframe на странице, который Я установил URL-адрес, чтобы получить новый токен доступа из авторизации Сервер.

4) Получите новый токен из хэш-фрагмента iframe, затем сохраните это в SPA и используйте для всех будущих запросов WebAPI.

1) SPA (вы) понятия не имеете, выбрал ли пользователь запоминающее решение. Его в AS направлении и должен быть полный черный ящик. Пропустить этот шаг.

2) Вы можете попробовать использовать токен доступа и ждать результата всегда.

3) Если токен доступа истек, и у вас нет обновления токена, вы все равно можете создать скрытый iframe и попытаться получить новый токен доступа.

4) Давайте предположим, что ваш AS предоставит возможность запомнить решение и не изменит его в будущем, а затем: ваш iframe получит новый токен доступа без взаимодействия с пользователем, после чего вы вернете результат в какой-то неизвестный срок. Результат можно проверить с помощью setInterval для чтения определенного файла cookie или iframe postmessage. Если вы не вернете данные по срокам, то произошел один из следующих сценариев:

  • lag, AS медленный, соединение медленное или ограничение по времени слишком жесткое.
  • Пользователь не выбрал запоминающее решение

В этом случае:

5) показать iframe с логином

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

StackOverflow < --- > сценарий Google (я могу только догадываться)

1) Вход пользователя, запрос авторизации

2) Пользователь регистрируется, SO получает токен доступа

3) SO пытается использовать токен доступа

4) SO возвращает результат + обновить токен

5) SO сохраняет токен обновления

6) SO имеет постоянный доступ к учетным записям пользователей Google