Тип токена маркера OAuth2RestTemplate

Я использую Spring Security OAuth2 с OAuth2RestTemplate для реализации клиента для защищенного OAuth 2.0 API REST. Поток проходит через шаги для успешного получения маркера доступа:

response.statusCode = 200
response.body = {"access_token":"9b90f8a84b939b8437a4fbaa8fff0052839cf6f5","expires_in":3600,"token_type":"bearer","scope":" read write","refresh_token":"e164f317a1708c3664025e9e56ce605cfe710474"}

Однако, когда код пытается использовать OAuth2RestTemplate для доступа к защищенному ресурсу, ответ не увенчался успехом:

GET request for "https://redacted.com/api/v1/clients" resulted in 400 (Bad Request)

Это связано с тем, что DefaultOAuth2RequestAuthenticator использует значение token_type ("предъявитель"), возвращенное с помощью access_token, чтобы сформировать заголовок проверки подлинности для запроса на защищенный ресурс:

request.getHeaders().set("Authorization", String.format("%s %s", tokenType, accessToken.getValue()));

Это приводит к тому, что поле учетных данных в заголовке авторизации запроса имеет префикс строки "предъявитель":

Request Header: "Authorization" "bearer a8f18cb3173c4cbbea44f4495dd5e5662156c391"

Однако, в соответствии с разделом спецификации использования токена OAuth 2.0 для указателя 2.1, поле заголовка запроса авторизации, формат поля учетных данных:

credentials = "Bearer" 1 * SP b64token

Обратите внимание, что в спецификации "Носитель" имеет верхний регистр. Это означает, что заголовок запроса должен быть:

Request Header: "Authorization" "Bearer a8f18cb3173c4cbbea44f4495dd5e5662156c391"

По-видимому, поставщик, которого мы отправляем, запрашивает, чтобы реализовать спецификацию узко, потому что проблема с капитализацией ("предъявитель" и "носитель") - это то, что приводит к сбою запроса на защищенный ресурс. Когда я изменяю DefaultOAuth2RequestAuthenticator, чтобы принудить префикс к заглавной записи, запрос преуспеть:

if ("bearer".equals(tokenType)) {
    tokenType = "Bearer";
}

Header key = Authorization values = Bearer 8efd4381f3470660291e700e4927012f288ad66c,
Sending GET request to https://redacted.com/api/v1/clients
Received "200 OK" response for GET request to https://redacted.com/api/v1/clients: [[{"id":"999999999","client_user_id":"a1b2c3d4e5f6"...

Я действительно не хочу иметь свою собственную вилку Spring Security OAuth2, чтобы исправить эту проблему. Как это работает для кого-то? Я что-то пропустил?

+2
источник поделиться
2 ответа

Я решил эту проблему этими кодами

    @Bean
public OAuth2RestOperations restTemplate(){

    AccessTokenRequest accessTokenRequest = new DefaultAccessTokenRequest();
    OAuth2ClientContext oAuth2ClientContext = new DefaultOAuth2ClientContext(accessTokenRequest);
    OAuth2RestTemplate oAuth2RestTemplate = new OAuth2RestTemplate( resource(),oAuth2ClientContext );
    oAuth2RestTemplate.setAuthenticator(new DefaultOAuth2RequestAuthenticator(){
        @Override
        public void authenticate(OAuth2ProtectedResourceDetails resource, OAuth2ClientContext clientContext, ClientHttpRequest request) {
            clientContext.setAccessToken(new DefaultOAuth2AccessToken(clientContext.getAccessToken()){
                @Override
                public String getTokenType() {
                    if ("bearer".equals(super.getTokenType())) {
                        return "Bearer";
                    }
                    return super.getTokenType();
                }
            });
            OAuth2AccessToken accessToken = clientContext.getAccessToken();
            super.authenticate(resource, clientContext, request);
        }
    });
+1
источник

Как оказалось, на самом деле это не работает для многих людей. Существует открытый вопрос в списке проблем весны-безопасности-oauth для решения этой проблемы (текущая веха 2.2.1):

Использовать OAuth2 token_type, равный "несущему" по умолчанию везде # 457

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

0
источник

Посмотрите другие вопросы по меткам или Задайте вопрос