Как программно авторизоваться на основе защищенного REST-API OpenId Connect? - PullRequest
0 голосов
/ 22 января 2020

Я реализовал REST-API на основе Spring Boot, защищенного сервером ресурсов Open Security 5.2 OpenID Connect. Сервер авторизации - IdentityServer4. Пока все хорошо, аутентификация с использованием Bearer Token (токен определяется через фиктивную веб-страницу) работает хорошо.

Теперь задача состоит в том, чтобы вызвать REST API от клиента, которому не требуется пользователь взаимодействие (веб-страница).

Я хотел бы предоставить пользователям API незащищенную конечную точку (/ авторизацию), которую можно использовать для получения токена носителя для любой дополнительной защищенной услуги. Имя пользователя и пароль должны быть переданы в качестве параметров запроса.

Я провел поиск в Интернете и изучил документы Spring, но я не нашел ничего, что отвечало бы моему варианту использования.

1 Ответ

0 голосов
/ 23 января 2020

Я реализовал относительно простое решение

@GetMapping
public ResponseEntity<GetTokenResponse> getToken(@RequestBody GetTokenRequest getTokenRequest) {

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

    MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
    formData.add("client_id", clientId);
    formData.add("client_secret", clientSecret);
    formData.add("grant_type", "password");
    formData.add("scope", scopes);
    formData.add("username", getTokenRequest.getUsername());
    formData.add("password", getTokenRequest.getPassword());

    RestTemplate restTemplate = new RestTemplate();
    HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(formData, headers);
    ResponseEntity<GetTokenResponse> response = restTemplate.postForEntity( tokenEndPoint, request , GetTokenResponse.class );

    String accessToken = response.getBody().getAccessToken();

    NimbusJwtDecoder decoder = NimbusJwtDecoder.withJwkSetUri(jwkSetUri).build();
    Jwt jwt = decoder.decode(accessToken);
    logger.debug("Headers:\n{}", jwt.getHeaders());
    logger.debug("Claims:\n{}", jwt.getClaims());
    logger.info("User {}, {} '{}' authorised.", jwt.getClaimAsString("given_name"), jwt.getClaimAsString("family_name"), jwt.getClaimAsString("sub"));

    return response;
}

Ответ содержит маркер канала-носителя и поэтому может использоваться для вызовов API.

...