0
votes

I have implement a REST-API based on Spring Boot secured by Spring Security 5.2 OpenID Connect resource server. The authorization server is an IdentityServer4. So far so good, the authentication using Bearer Token (the token is determined via a dummy web page) works well.

The challenge now is to call the REST API from a client that does not require user interaction (web page).

I would like to provide the API users with an unsecured endpoint (/authorization) which can be used to receive the Bearer Token for any further secured service. Username and password should be passed as request parameters.

I have search the web and studied the docs from Spring but I did not have found something which addresses my use case.

1
if you are communicating on HTTPS then you are secured, but if you want to use the only HTTP then you need to take care of encryption/decryption mechanism. - Pavan Kumar Jorrigala
yes, all communication is via https - Alex

1 Answers

0
votes

I implemented a relatively simple solution

@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;
}

The response contains the bearer token and can therefore be used for the API calls.