1. Обзор
Иногда API OAuth2 могут немного отличаться от стандартных, и в этом случае нам нужно сделать некоторые настройки для стандартных запросов OAuth2.
Spring Security 5.1 обеспечивает поддержку настройки авторизации OAuth2 и запросов токенов.
В этом руководстве мы рассмотрим, как настроить параметры запроса и обработку ответов.
2. Запрос на пользовательскую авторизацию
Во-первых, мы настроим запрос на авторизацию OAuth2. Мы можем изменять стандартные параметры и добавлять дополнительные параметры в запрос авторизации по мере необходимости.
Для этого нам необходимо реализовать наши собственные Распознаватель запросов авторизации OAuth2 :
public class CustomAuthorizationRequestResolver implements OAuth2AuthorizationRequestResolver { private OAuth2AuthorizationRequestResolver defaultResolver; public CustomAuthorizationRequestResolver( ClientRegistrationRepository repo, String authorizationRequestBaseUri) { defaultResolver = new DefaultOAuth2AuthorizationRequestResolver(repo, authorizationRequestBaseUri); } // ... }
Обратите внимание, что мы использовали По умолчанию Распознаватель запросов авторизации OAuth2 для обеспечения базовой функциональности.
Мы также переопределим методы resolve () , чтобы добавить нашу логику настройки:
public class CustomAuthorizationRequestResolver implements OAuth2AuthorizationRequestResolver { //... @Override public OAuth2AuthorizationRequest resolve(HttpServletRequest request) { OAuth2AuthorizationRequest req = defaultResolver.resolve(request); if(req != null) { req = customizeAuthorizationRequest(req); } return req; } @Override public OAuth2AuthorizationRequest resolve(HttpServletRequest request, String clientRegistrationId) { OAuth2AuthorizationRequest req = defaultResolver.resolve(request, clientRegistrationId); if(req != null) { req = customizeAuthorizationRequest(req); } return req; } private OAuth2AuthorizationRequest customizeAuthorizationRequest( OAuth2AuthorizationRequest req) { // ... } }
Мы добавим наши настройки позже, используя наш метод customize Authorization Request () , как мы обсудим в следующих разделах.
После реализации нашего обычая Распознаватель запросов авторизации OAuth2 , нам нужно добавить его в нашу конфигурацию безопасности:
@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.oauth2Login() .authorizationEndpoint() .authorizationRequestResolver( new CustomAuthorizationRequestResolver( clientRegistrationRepository(), "/oauth2/authorize-client")) //... } }
Здесь мы использовали oauth2 Login().конечная точка авторизации().распознаватель запросов на авторизацию() чтобы ввести наш обычай Распознаватель запросов авторизации OAuth2.
3. Настройка Стандартные параметры запроса авторизации
Теперь давайте обсудим фактическую настройку. Мы можем изменить Запрос авторизации OAuth2 столько, сколько мы хотим.
Для начала, мы можем изменить стандартный параметр для каждого запроса на авторизацию.
Мы можем, например, сгенерировать свой собственный параметр “состояние” :
private OAuth2AuthorizationRequest customizeAuthorizationRequest( OAuth2AuthorizationRequest req) { return OAuth2AuthorizationRequest .from(req).state("xyz").build(); }
4. Дополнительные Параметры запроса авторизации
Мы также можем добавить дополнительные параметры в наш Запрос авторизации OAuth2 с использованием дополнительных параметров() метода OAuth2AuthorizationRequest и передачей Карты:
private OAuth2AuthorizationRequest customizeAuthorizationRequest( OAuth2AuthorizationRequest req) { MapextraParams = new HashMap (); extraParams.putAll(req.getAdditionalParameters()); extraParams.put("test", "extra"); return OAuth2AuthorizationRequest .from(req) .additionalParameters(extraParams) .build(); }
Мы также должны убедиться, что включили старые дополнительные параметры , прежде чем добавлять новые.
Давайте рассмотрим более практический пример, настроив запрос на авторизацию, используемый с сервером авторизации Okta.
4.1. Пользовательский запрос авторизации Okta
Okta имеет дополнительные дополнительные параметры для запроса авторизации, чтобы предоставить пользователю больше возможностей. Например, idp , который указывает поставщика удостоверений.
Поставщик удостоверений по умолчанию в порядке, но мы можем настроить его с помощью параметра idp :
private OAuth2AuthorizationRequest customizeOktaReq(OAuth2AuthorizationRequest req) { MapextraParams = new HashMap (); extraParams.putAll(req.getAdditionalParameters()); extraParams.put("idp", "https://idprovider.com"); return OAuth2AuthorizationRequest .from(req) .additionalParameters(extraParams) .build(); }
5. Пользовательский запрос токена
Теперь мы посмотрим, как настроить запрос токена OAuth2.
Мы можем настроить запрос токена, настроив Клиент ответа OAuth2 accessToken .
Реализация по умолчанию для OAuth2 accessToken Response Client is DefaultAuthorizationCodeTokenResponseClient .
Мы можем настроить сам запрос токена, предоставив пользовательский Конвертер сущностей запроса , и мы даже можем настроить обработку ответа токена, настроив DefaultAuthorizationCodeTokenResponseClient | RestOperations :
@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.tokenEndpoint() .accessTokenResponseClient(accessTokenResponseClient()) //... } @Bean public OAuth2AccessTokenResponseClientaccessTokenResponseClient(){ DefaultAuthorizationCodeTokenResponseClient accessTokenResponseClient = new DefaultAuthorizationCodeTokenResponseClient(); accessTokenResponseClient.setRequestEntityConverter(new CustomRequestEntityConverter()); OAuth2AccessTokenResponseHttpMessageConverter tokenResponseHttpMessageConverter = new OAuth2AccessTokenResponseHttpMessageConverter(); tokenResponseHttpMessageConverter.setTokenResponseConverter(new CustomTokenResponseConverter()); RestTemplate restTemplate = new RestTemplate(Arrays.asList( new FormHttpMessageConverter(), tokenResponseHttpMessageConverter)); restTemplate.setErrorHandler(new OAuth2ErrorResponseErrorHandler()); accessTokenResponseClient.setRestOperations(restTemplate); return accessTokenResponseClient; } }
Мы можем ввести свои собственные Клиент ответа OAuth2 accessToken с помощью конечная точка токена().клиент ответа на Токен доступа().
Чтобы настроить параметры запроса токенов, мы реализуем Custom Request Entity Converter. Аналогично, чтобы настроить обработку ответа на токен, мы реализуем Пользовательский конвертер ответов на токен.
Мы обсудим как Конвертер сущностей пользовательских запросов , так и Конвертер ответов пользовательских токенов в следующих разделах.
6. Дополнительные Параметры Запроса токена
Теперь мы посмотрим, как добавить дополнительные параметры в наш запрос токена, создав пользовательский Конвертер :
public class CustomRequestEntityConverter implements Converter> { private OAuth2AuthorizationCodeGrantRequestEntityConverter defaultConverter; public CustomRequestEntityConverter() { defaultConverter = new OAuth2AuthorizationCodeGrantRequestEntityConverter(); } @Override public RequestEntity> convert(OAuth2AuthorizationCodeGrantRequest req) { RequestEntity> entity = defaultConverter.convert(req); MultiValueMap params = (MultiValueMap ) entity.getBody(); params.add("test2", "extra2"); return new RequestEntity<>(params, entity.getHeaders(), entity.getMethod(), entity.getUrl()); } }
Наш Конвертер трансформирует Запрос на предоставление кода авторизации OAuth2 К Просьба.
Мы использовали конвертер по умолчанию OAuth2 Authorization Code Grant Request Entity Converter для обеспечения базовой функциональности и добавления дополнительных параметров в тело RequestEntity .
7. Обработка пользовательских Ответов на Токены
Теперь мы настроим обработку ответа токена.
Мы можем использовать конвертер ответов токенов по умолчанию OAuth2 accessToken Ответ HttpMessageConverter в качестве отправной точки.
Мы осуществим Пользовательский конвертер Ответов на токены чтобы справиться с “сфера применения” параметр по-разному:
public class CustomTokenResponseConverter implements Converter
Преобразователь ответов токенов преобразует Map в Ответ OAuth2 accessToken.
В этом примере мы проанализировали параметр “scope” как разделенную запятыми вместо разделенной пробелом строки .
Давайте рассмотрим еще один практический пример, настроив ответ токена с помощью LinkedIn в качестве сервера авторизации.
7.1. Обработка ответов на токены LinkedIn
Наконец, давайте посмотрим, как обрабатывать ответ на токен LinkedIn . Это содержит только access_token и expires_in, но нам также нужен token_type.
Мы можем просто реализовать ваш собственный конвертер ответов токенов и установить token_type вручную:
public class LinkedinTokenResponseConverter implements Converter
8. Заключение
В этой статье мы узнали, как настроить авторизацию OAuth2 и запросы токенов, добавив или изменив параметры запроса.
Полный исходный код примеров доступен на GitHub .