Spring Oauth2 - настройка TokenEndpoint от @RequestParam до @RequestBody - PullRequest
0 голосов
/ 06 июня 2018

Я использую стандартную конфигурацию Spring-Security, это мой pom.xml:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
        <relativePath></relativePath>
    </parent>

<dependencies>
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
        </dependency>
</dependencies>

Я должен изменить стандартный запрос токена:

Оригинальный запрос токена:

@RequestMapping(value = "/oauth/token", method=RequestMethod.GET)
public ResponseEntity<OAuth2AccessToken> getAccessToken(Principal principal, @RequestParam Map<String, String> parameters) throws HttpRequestMethodNotSupportedException

Требуемый запрос токена

@RequestMapping(value = "/oauth/login", method=RequestMethod.POST)
public ResponseEntity<OAuth2AccessToken> postAccessToken(Principal principal, @RequestBody UserLogin userLogin) throws HttpRequestMethodNotSupportedException

Возможно ли это?

Я расширяю TokenEndpoint следующим образом, но не работает:

public class CustomTokenEndpoint extends TokenEndpoint {

@RequestMapping(value = "/oauth/login", method=RequestMethod.POST)
public ResponseEntity<OAuth2AccessToken> postAccessToken(Principal principal, @RequestBody UserLogin userLogin) throws HttpRequestMethodNotSupportedException {
        return postAccessToken(principal, userLogin.getParameters());
    }
}

1 Ответ

0 голосов
/ 11 июня 2018

Это не будет работать так, потому что ваш пользовательский класс конечных точек не будет загружен в цепочку фильтров Spring.Не нужно продлевать TokenEndpoint.Вы можете создать новую конечную точку и заставить ее делать то, что делает исходная конечная точка /oauth/token.

Следующий код должен дать вам преимущество.Обратитесь к этому коду, чтобы понять, что должна делать ваша новая конечная точка.Это похоже на TokenEndpoint#postAccessToken(...).

@RequestMapping(value = "/oauth/login", method = RequestMethod.POST)
    public ResponseEntity<OAuth2AccessToken> postAccessToken(final Principal principal, @RequestBody final UserLogin userLogin) throws HttpRequestMethodNotSupportedException {
        if (!(principal instanceof Authentication)) {
            throw new InsufficientAuthenticationException("Client authentication information is missing.");
        }

        final Authentication client = (Authentication) principal;
        if (!client.isAuthenticated()) {
            throw new InsufficientAuthenticationException("The client is not authenticated.");
        }
        String clientId = client.getName();
        if (client instanceof OAuth2Authentication) {
            // Might be a client and user combined authentication
            clientId = ((OAuth2Authentication) client).getOAuth2Request().getClientId();
        }

        final ClientDetails authenticatedClient = clientDetailsService.loadClientByClientId(clientId);
        final TokenRequest tokenRequest = oAuth2RequestFactory.createTokenRequest(parameters, authenticatedClient);

        final Map<String, String> parameters = new HashMap<>();
        parameters.put("username", userLogin.getUsername());
        parameters.put("password", userLogin.getPassword());
        parameters.put("grant_type", userLogin.getGrantType());
        parameters.put("refresh_token", userLogin.getRefreshToken());
        parameters.put("scope", userLogin.getScope());

        if (StringUtils.isNotBlank(clientId)) {
            // Only validate the client details if a client authenticated during this request.
            if (!clientId.equals(tokenRequest.getClientId())) {
                // Double check to make sure that the client ID in the token request is the same as that in the authenticated client
                throw new InvalidClientException(String.format("Given client ID [%s] does not match the authenticated client", clientId));
            }
        }

        if (authenticatedClient != null) {
            oAuth2RequestValidator.validateScope(tokenRequest, authenticatedClient);
        }
        if (!hasText(tokenRequest.getGrantType())) {
            throw new InvalidRequestException("Missing grant type");
        }

        final OAuth2AccessToken token;

        if (isRefreshTokenRequest(parameters)) {
            // A refresh token has its own default scopes, so we should ignore any added by the factory here.
            tokenRequest.setScope(OAuth2Utils.parseParameterList(parameters.get(OAuth2Utils.SCOPE)));
            token = refreshTokenGranter.grant(tokenRequest.getGrantType().toLowerCase(), tokenRequest);
        } else {
            token = tokenGranter.grant(tokenRequest.getGrantType().toLowerCase(), tokenRequest);
        }

        if (Objects.isNull(token)) {
            throw new UnsupportedGrantTypeException("Unsupported grant type: " + tokenRequest.getGrantType());
        }

        return new ResponseEntity<>(token, HttpStatus.OK);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...