Java Spring Security OAuth2: принимать учетные данные клиента через POST - PullRequest
0 голосов
/ 19 сентября 2018

У меня довольно простая настройка Spring Boot, и я установил Spring Security, и мне удалось успешно настроить OAuth2 для защиты моего API.

У меня были некоторые проблемы несколько дней назад, и спросил(и ответил) на вопрос относительно достижения моей конечной точки /oauth/token.Вскоре я понял, что проблема заключалась в том, что я пытался отправить свои учетные данные клиента в теле моего запроса POST, но конечная точка токена настроена в Spring Security для приема учетных данных клиента (client_id и secret)вместо этого через HTTP Basic Auth.

Большая часть моего опыта использования API-интерфейсов OAuth2 была связана с отправкой учетных данных клиента в теле запроса POST, и мне было интересно, можно ли настроить Spring Security для работы втаким же образом?

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

security.oauth2.client.clientAuthenticationScheme=form

Это моя конфигурация сервера авторизации.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.approval.UserApprovalHandler;
import org.springframework.security.oauth2.provider.token.TokenStore;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private UserApprovalHandler userApprovalHandler;

    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("client_id")
                .secret("secret")
                .authorizedGrantTypes("password", "authorization_code", "refresh_token")
                .scopes("read", "write")
                .accessTokenValiditySeconds(600)
                .refreshTokenValiditySeconds(3600);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(this.tokenStore)
                .userApprovalHandler(this.userApprovalHandler)
                .authenticationManager(this.authenticationManager);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) {
        security.tokenKeyAccess("permitAll()")
                .checkTokenAccess("isAuthenticated()")
                .passwordEncoder(this.passwordEncoder);
    }
}

1 Ответ

0 голосов
/ 20 сентября 2018

Как отметил @chrylis в комментариях, хитрость заключается в использовании метода allowFormAuthenticationForClients на AuthorizationServerSecurityConfigurer при настройке сервера авторизации.В моем случае у меня есть это в моем AuthorizationServerConfig классе:

@Override
public void configure(AuthorizationServerSecurityConfigurer security) {
    security.tokenKeyAccess("permitAll()")
            .checkTokenAccess("isAuthenticated()")
            .passwordEncoder(this.passwordEncoder)
            .allowFormAuthenticationForClients();
}

, что позволит передавать учетные данные клиента через стандартные параметры, такие как в теле запроса POST (или в строке запроса), хотя Spring предпочитает использовать HTTP Basic Auth, объединяя client_id и secret вместе с двоеточием (<client_id>:<secret>), base-64 кодирует результат, добавляя к нему префикс Basic и передавая его Authorizationзаголовок, так что вы получите что-то вроде этого:

Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l
...