Разработчики знают, что OAuth 2.0 и OpenID Connect (OIDC) являются мощными инструментами для добавления аутентификации и авторизации в современные веб-приложения.
Теперь вы можете заставить эти стандарты делать еще больше для вас с помощью новых встроенных крючков Okta . Этот пост покажет вам, как использовать встроенные перехватчики для передачи информации о токенах, которые вы получаете от Okta через OIDC и OAuth.
Сначала вы установите приложение OIDC в Okta, чтобы увидеть типы токенов, которые вы получите. Затем вы настроите приложение Spring Boot API, которое позволит вам регистрировать ваши любимые сорта пива (это основано на предыдущем посте моего друга и коллеги, Мэтта Рейбла, который увлечен хорошим пивом). Это приложение Spring Boot также имеет конечные точки API для регистрации перехватчиков токенов в Okta и для обслуживания запросов на исправление токенов из Okta. К тому времени, как вы закончите, вы увидите, что ваши любимые сорта пива теперь включены в полезную нагрузку токена благодаря зарегистрированным хукам.
Чтобы подготовиться к практическим частям этого поста, настройтесь на следующее:
- Создайте бесплатную организацию разработчиков Okta по адресу https://developer.okta.com/signup/.
- Установите HTTPie , современную замену curl для взаимодействия с конечными точками API позже
- Установите ngrok , приложение, которое позволяет публичный доступ к локально работающему серверу
- Необязательно: Создайте бесплатную учетную запись Heroku по адресу https://signup.heroku.com/.
Для начала давайте сделаем шаг назад и поговорим немного больше о OIDC и OAuth.
Трехминутный обзор OpenID Connect и OAuth 2.0
В начале были разрозненные сайты, которые не общались друг с другом, и все были грустными.
Такие сайты, как Yelp, начали получать доступ к контактной информации, которая была у вас в контактах Google. Итак, Yelp, естественно, собрал ваше имя пользователя и пароль Google, чтобы он мог получить доступ к вашим контактам. Вы дали Yelp свое разрешение, так что все было хорошо, да? Нет! С вашим именем пользователя и паролем Yelp может получить доступ к вашей электронной почте, вашим документам — всему, что у вас было в Google — не только вашим контактам. И что еще хуже, Yelp пришлось хранить ваш пароль таким образом, чтобы он мог использовать его в виде открытого текста, и не было стандартного способа отозвать ваше согласие на Yelp для доступа к вашей учетной записи Google.
Нам нужна была структура авторизации, которая позволяла бы вам предоставлять доступ к определенной информации без вашего пароля. Кий OAuth.
Используйте OAuth 2.0 для делегированной авторизации
Три ревизии спустя, мы находимся в OAuth 2.0 (до него было 1.0 и 1.0a) и все в порядке с миром. Теперь приложение, такое как Yelp (a Client Application
), может запросить Access Token
услугу, такую как Google (an Authorization Server
). Вы (the Resource Owner
) входите в Google со своими учетными данными и даете Consent
Yelp доступ к вашим контактам (и только вашим контактам). Access Token
Yelp обращается к API контактов Google Resource Server
и получает ваши контакты. Yelp никогда не видит ваш пароль и никогда не имеет доступа ни к чему большему, чем вы согласились. И вы можете отозвать свое согласие в любое время.
Используйте OpenID Connect для идентификации
В этом новом мире согласия и авторизации не хватало только одного: идентичности. Cue OpenID Connect. OIDC — это тонкий слой поверх OAuth 2.0, который представляет токен нового типа: токен идентификации. В этих криптографически подписанных токенах в формате JWT содержится информация об аутентифицированном пользователе. Это открыло дверь на новый уровень взаимодействия и единого входа.
OAuth (и, соответственно, OIDC) используют ряд определенных Flows
для управления взаимодействиями между Client App
, Authorization Server
и Resource Server
. В этом посте вы сосредоточитесь на Authorization Code Flow
. Этот поток предназначен для запуска из вашего браузера и выглядит так:
- Yelp хочет получить доступ к вашим контактам. Он представляет собой кнопку, чтобы связать ваши контакты Google.
- Когда вы нажимаете кнопку, вы перенаправляетесь в Google, где вы входите под своим именем пользователя и паролем (если вы еще не вошли в систему).
- Google показывает вам экран, сообщающий, что Yelp хотел бы получить доступ только для чтения к вашим контактам.
- Как только вы дадите свое согласие, Google перенаправит обратно в Yelp через ваш браузер временный код (называемый кодом авторизации).
- Используя этот код, Yelp связывается с Google, чтобы обменять его на токен доступа
- Google проверяет код и, если все проверено, выдает токен доступа с ограниченными возможностями (доступ только для чтения к вашим контактам) для Yelp
- Затем Yelp представляет токен доступа в API контактов Google.
- API контактов Google проверяет токен и, если запрос соответствует возможностям, указанным токеном, возвращает ваш список контактов в Yelp
Настройте свою организацию Okta для OIDC и OAuth 2.0
В этом разделе вы собираетесь создать приложение OpenID Connect в Okta. Затем вы отработаете приложение OIDC с помощью небольшого приложения OIDC для игровой площадки, которое я создал на Heroku. Кодирование не требуется! (Что будет позже).
После входа в свою организацию Okta перейдите в Приложения из меню верхнего уровня. Нажмите: Добавить приложение . Нажмите на третий ящик с надписью над Web и нажмите кнопку Далее .
Введите следующее:
поле | стоимость |
---|---|
имя | OIDC Beers |
URI перенаправления входа | https://okta-oidc-fun.herokuapp.com/flow_result |
Тип гранта разрешен | Проверьте код авторизации и неявный (гибридный) |
Нажмите Готово .
Примечание. В настоящее время наилучшим руководством для OAuth 2.0 (как описано здесь ) является НЕ использовать неявный поток. Мы используем его здесь в демонстрационных целях.
Прокрутите вниз и скопировать Client ID
и Client secret
значение. Вы будете нуждаться в этом позже.
OIDC Fun на Heroku
Я создал приложение для игровых площадок OIDC, чтобы иметь возможность использовать различные доступные потоки. Это пригодится, чтобы увидеть приложение OIDC, которое вы только что создали в действии.
Перейдите на https://okta-oidc-fun.herokuapp.com
Вы увидите страницу с формой и несколькими кнопками переключения. Изначально он указывает на мою организацию Okta. Но вы можете изменить его на свою организацию Okta, заполнив форму.
Обновите значения в соответствии со следующим:
поле | стоимость |
---|---|
Okta Org | полностью квалифицированный домен для вашей организации (НЕТ https: //) |
ID сервера авторизации | дефолт |
Идентификатор клиента OIDC | Идентификатор клиента, который вы скопировали при создании приложения OIDC |
response_type | DESELECT код , выберите id_token и токен |
Прокрутите вниз и нажмите на ссылку. Откроется новая вкладка, где вы можете пройти аутентификацию в своей организации Okta. Затем вы будете перенаправлены обратно, где увидите идентификационный токен и токен доступа. Нажмите Проверить идентификатор токена, и вы увидите полезную нагрузку, закодированную в этот токен.
Вы уже видели, какие токены может генерировать ваше приложение OpenID Connect в Okta.
В оставшейся части этого поста вы узнаете, как создать ловушку, которая будет добавлять пользовательские утверждения к идентификатору токена. Это происходит во время полета, но до того, как идентификационный токен будет подписан. Это означает, что вы все еще можете безопасно проверить криптографическую подпись.
Оставьте эту вкладку браузера открытой. Вы будете использовать токен доступа чуть позже.
Настройте API любимого пива
Зайдите и получите исходный код этого поста с GitHub .
Это приложение Spring Boot, которое использует Okta Spring Boot Starter для легкой интеграции с OpenID Connect и OAuth 2.0.
Он использует базу данных H2 в памяти и Spring Data JPA для простого объектно-реляционного отображения. Он также использует отличный проект Lombok, потому что — Кто любит писать геттеры и сеттеры?
В приложении есть API для указания вашего любимого пива, а также API для обработки входящего запроса ловушки от Okta и возврата ответа на патч ID токена.
В папке src / main / resources вы увидите application.sample.yml
файл. Скопируйте это application.yml
в ту же папку.
Вам нужно настроить application.yml
файл, используя значения, которые вы собрали из настроек, которые мы сделали выше. Это включает в себя эмитент , ClientId и clientSecret значение. Кроме того, можно при необходимости изменить id
и password
значение , что вы хотите. Эти значения используются позже с API-интерфейсом Hooks. Если у вас есть эти наборы, вы можете запустить приложение так:
Оболочка
xxxxxxxxxx
1
./mvnw spring-boot:run
Примечание: вам понадобится Java 11 или выше, чтобы запустить этот пример. Если вы работаете на Mac, я рекомендую SDKMAN для управления версиями Java.
После запуска приложения вы увидите вывод, указывающий, что база данных H2 в памяти была заправлена некоторыми напитками:
Простой текст
xxxxxxxxxx
1
Beer(id=1, name=Kentucky Brunch Brand Stout)
2
Beer(id=2, name=Marshmallow Handjee)
3
Beer(id=3, name=Barrel-Aged Abraxas)
4
Beer(id=4, name=Hunahpu's Imperial Stout)
5
Beer(id=5, name=King Julius)
6
Beer(id=6, name=Heady Topper)
7
Beer(id=7, name=Budweiser)
8
Beer(id=8, name=Coors Light)
9
Beer(id=9, name=PBR)
Упражнение Применение пива
Теперь вы собираетесь использовать Beers API для добавления вашего любимого пива. Но все конечные точки API защищены с помощью OIDC. Это где ваш токен доступа из ранее приходит.
Выполните следующую команду, чтобы добавить пиво в список избранного:
HTTP
xxxxxxxxxx
1
http \
2
localhost:8080/api/add-beer \
3
name=Heineken \
4
Authorization:"Bearer <your access token>"
Если все пойдет хорошо, вы получите ответ, подобный этому:
HTTP
xxxxxxxxxx
1
HTTP/1.1 200
2
...
3
[
5
{ "id": 10, "name": "Heineken" }
6
]
Приложение одновременно создало новую запись пива и добавило ее в список избранных.
ПРИМЕЧАНИЕ. Поскольку приложение использует базу данных в памяти, если вы перезапустите приложение, вам потребуется повторно добавить ваши любимые сорта пива с помощью этого API.
Затем вы установите встроенный хук, который добавит beers
заявку к вашему токену ID на лету.
Получите ваши любимые пива в свой токен
Чтобы использовать API обработки хуков, Okta должна иметь возможность звонить на него через общедоступный Интернет. В «реальной жизни» вы должны где-то развернуть свое приложение и настроить его так, чтобы Okta могла взаимодействовать с ним.
В демонстрационных целях вы собираетесь использовать службу ngrok , которая выдает уникальный общедоступный домен, который подключен к локально запущенному приложению Spring Boot.
Начните с выдачи этой команды на отдельной вкладке терминала:
Оболочка
xxxxxxxxxx
1
ngrok http 8080
Вы увидите вывод так:
Простой текст
xxxxxxxxxx
1
ngrok by @inconshreveable (Ctrl+C to quit)
2
Session Status online
4
Session Expires 6 hours, 30 minutes
5
Version 2.3.29
6
Region United States (us)
7
Web Interface http://127.0.0.1:4040
8
Forwarding http://e3fc9a95.ngrok.io -> http://localhost:8080
9
Forwarding https://e3fc9a95.ngrok.io -> http://localhost:8080
10
Connections ttl opn rt1 rt5 p50 p90
12
0 0 0.00 0.00 0.00 0.00
Скопируйте ссылку https ( https://e3fc9a95.ngrok.io
в моем случае), так как она скоро понадобится.
Настройка встроенных крючков Okta
Публично доступное (благодаря ngrok) приложение Spring Boot, которое вы запускаете, полностью настроено на получение запросов о подключении от Okta. Но ваша организация Okta еще не готова к этому.
Во-первых, вам нужно зарегистрировать встроенный хук токена в Okta.
В административной консоли своей организации перейдите в Рабочий процесс> Встроенные хуки . Нажмите: Добавить Inline Hook> Token .
Введите в форму следующее и нажмите « Сохранить» :
поле | Стоимость |
---|---|
имя | Beers Hook |
URL | {ваш ngrok url} / api / hooks / apiam |
Поле аутентификации | авторизация |
Секрет аутентификации | Basic bWVAZXhhbXBsZS5jb206d2hhdGV2cw == |
Это Authentication field
заголовок, который Okta будет использовать для аутентификации вашего хука. Это Authentication secret
значение, которое будет отправлено в заголовке авторизации.
Примечание. Секретное значение аутентификации находится в application.yml
файле. Если вы изменили значения идентификатора и пароля перехвата, вам потребуется пересчитать базовую строку авторизации и отразить это значение в приведенных выше настройках.
Крюк теперь создан в вашей организации Okta.
В приложении Spring Boot включена базовая аутентификация на конечных точках перехвата через WebSecurityConfiguration.java
:
Джава
xxxxxxxxxx
1
2
public class WebSecurityConfiguration {
3
"#{ @environment['okta.hooks.id'] }") (
6
private String hooksId;
7
"#{ @environment['okta.hooks.password'] }") (
9
private String hooksPassword;
10
12
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
13
auth.inMemoryAuthentication()
14
.withUser(hooksId).password(passwordEncoder().encode(hooksPassword))
15
.authorities("ROLE_USER");
16
}
17
19
public PasswordEncoder passwordEncoder() {
20
return new BCryptPasswordEncoder();
21
}
22
24
1) (
25
public static class HooksConfiguration extends WebSecurityConfigurerAdapter {
26
28
public void configure(HttpSecurity http) throws Exception {
29
http
30
.antMatcher("/api/hooks/**")
31
.csrf().disable()
32
.authorizeRequests()
33
.anyRequest().authenticated()
34
.and()
35
.httpBasic();
36
}
37
}
38
40
2) (
41
public static class GlobalConfig extends WebSecurityConfigurerAdapter {
42
44
public void configure(HttpSecurity http) throws Exception {
45
http.authorizeRequests()
46
.anyRequest().authenticated()
47
.and()
48
.oauth2ResourceServer().jwt();
49
}
50
}
51
}
Обычная аутентификация используется для /api/hooks/**
конечной точки, а OAuth 2.0 используется для всего остального.
Анатомия Token Transformation Inline Hook
Прежде чем мы настроим ваш Сервер авторизации для использования ловушки, давайте посмотрим на суть кода, который позволяет идентифицировать токен со списком ваших любимых сортов пива.
Вот метод из HooksController
:
Джава
xxxxxxxxxx
1
"/apiam") (
2
public TokenHookResponse apiam( TokenHookRequest request) {
3
String login = request.getData().getContext().getUser().getProfile().getLogin();
4
Person person = personRepository.findByEmail(login);
5
TokenHookResponse response = new TokenHookResponse();
7
if (person != null) {
8
IDTokenPatchResponse idTokenPatchResponse = new IDTokenPatchResponse();
9
idTokenPatchResponse.getValue().add(
10
new TokenPatchResponse.Value(
11
"add", "/claims/beers", transformBeers(person.getFavoriteBeers())
12
)
13
);
14
response.getCommands().add(idTokenPatchResponse);
15
}
16
return response;
17
}
В TokenHookRequest
класс использует Ломбок и некоторые инициализации по умолчанию , чтобы убедиться , что вы не получите NullPointerException
.
В запросе о подключении токена есть много информации, которую Okta отправляет в контроллер. Я смоделировал только то, что нам нужно, сделав @JsonIgnoreProperties(ignoreUnknown = true)
аннотацию либеральным образом . Вы можете увидеть пример полного запроса JSON здесь .
Используя login
значение из запроса, код выполняет поиск в базе данных, чтобы извлечь Person
связанный с этим логином. Когда вы добавили в свой список любимых сортов пива ранее, Person
для вас была создана запись.
Затем код устанавливает, TokenHookResponse
который (потенциально) будет иметь список команд для исправления одного (или обоих) идентификатора токена и доступа к aoken. В этом примере мы собираемся только пропатчить идентификационный токен.
Критическая линия такова:
Джава
xxxxxxxxxx
1
new TokenPatchResponse.Value("add", "/claims/beers", transformBeers(p.getFavoriteBeers()))
Вот где список названий пива добавляется к ответу, приложенному к beers
иску. Ответ JSON выглядит следующим образом:
JSON
xxxxxxxxxx
1
{
2
"commands": [
3
{
4
"type": "com.okta.identity.patch",
5
"value": [
6
{
7
"op": "add",
8
"path": "/claims/beers",
9
"value": ["Heineken"]
10
}
11
]
12
}
13
]
14
}
Последний шаг, чтобы связать все это вместе, - настроить сервер авторизации для использования ловушки.
Добавьте пиво в свой токен
Нажмите API> Серверы авторизации в меню верхнего уровня. Нажмите по умолчанию . Нажмите Политики доступа . Прокрутите вниз и щелкните значок карандаша рядом с Default Policy Rule
.
Выберите Beers Hook из Use this inline hook
меню.
Нажмите Обновить правило .
Откройте вкладку браузера и перейдите к localhost:4040
. Это интерфейс мониторинга ngrok.
Теперь вы можете вернуться на игровую площадку OIDC раньше. Закройте вкладку результатов с помощью идентификатора токена и токена доступа. Нажмите на ссылку еще раз со страницы детской площадки. Нажмите Validate ID Token и пр. Voilà - вы увидите beers
претензию с любым пивом, которое вы добавили в избранное.
Вернитесь на вкладку мониторинга ngrok, и вы увидите запрос от Okta и ответ из приложения Spring Boot.
Узнайте больше о безопасной единой регистрации, OAuth 2.0 и Spring Boot
Okta Spring Boot Starter позволяет вам интегрировать ваши приложения Spring Boot с Okta с помощью всего лишь нескольких строк кода и трех свойств конфигурации.
Наряду с нашим Spring Boot Starter, сервис OpenID Connect от Okta не только соответствует стандарту, но и предоставляет вам сложный интерфейс единого входа, где один и тот же пользователь может получить доступ ко многим различным приложениям OIDC, каждое из которых имеет собственный набор требований и конфигурации. Помните: OIDC работает поверх OAuth 2.0 - он не автономен. Принимая во внимание, что OAuth фокусируется исключительно на авторизации, OIDC явно добавляет проблемы идентификации и аутентификации.
Если вы хотите узнать больше об OAuth и Spring Boot, вас могут заинтересовать следующие посты:
- Безопасный обмен данными между серверами с помощью Spring Boot и OAuth 2.0
- OAuth 2.0 для нативных и мобильных приложений
- OAuth 2.0 неявный поток мертв?
Как то, что вы узнали сегодня? Подпишитесь на нас в Твиттере и подпишитесь на наш канал на YouTube, чтобы получить больше интересного контента!