All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sap.cloud.security.xsuaa.client.DefaultOAuth2TokenService Maven / Gradle / Ivy

There is a newer version: 3.5.6
Show newest version
/**
 * SPDX-FileCopyrightText: 2018-2023 SAP SE or an SAP affiliate company and Cloud Security Client Java contributors
 * 

* SPDX-License-Identifier: Apache-2.0 */ package com.sap.cloud.security.xsuaa.client; import com.sap.cloud.security.servlet.MDCHelper; import com.sap.cloud.security.xsuaa.Assertions; import com.sap.cloud.security.xsuaa.http.HttpHeaders; import com.sap.cloud.security.xsuaa.tokenflows.TokenCacheConfiguration; import com.sap.cloud.security.xsuaa.util.HttpClientUtil; import org.apache.http.Header; import org.apache.http.HttpStatus; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.annotation.Nonnull; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.util.AbstractMap; import java.util.Arrays; import java.util.List; import java.util.Map; import static com.sap.cloud.security.xsuaa.client.OAuth2TokenServiceConstants.*; import static org.apache.http.HttpHeaders.USER_AGENT; public class DefaultOAuth2TokenService extends AbstractOAuth2TokenService { private static final Logger LOGGER = LoggerFactory.getLogger(DefaultOAuth2TokenService.class); private final CloseableHttpClient httpClient; public DefaultOAuth2TokenService(@Nonnull CloseableHttpClient httpClient) { this(httpClient, TokenCacheConfiguration.defaultConfiguration()); } public DefaultOAuth2TokenService(@Nonnull CloseableHttpClient httpClient, @Nonnull TokenCacheConfiguration tokenCacheConfiguration) { super(tokenCacheConfiguration); Assertions.assertNotNull(httpClient, "http client is required"); this.httpClient = httpClient; } @Override protected OAuth2TokenResponse requestAccessToken(URI tokenEndpointUri, HttpHeaders headers, Map parameters) throws OAuth2ServiceException { HttpHeaders requestHeaders = new HttpHeaders(); headers.getHeaders().forEach(h -> requestHeaders.withHeader(h.getName(), h.getValue())); requestHeaders.withHeader(MDCHelper.CORRELATION_HEADER, MDCHelper.getOrCreateCorrelationId()); HttpPost httpPost = createHttpPost(tokenEndpointUri, requestHeaders, parameters); LOGGER.debug("access token request {} - {}", headers, parameters.entrySet().stream() .map(e -> { if (e.getKey().contains(PASSWORD) || e.getKey().contains(CLIENT_SECRET) || e.getKey().contains(ASSERTION)) { return new AbstractMap.SimpleImmutableEntry<>(e.getKey(), "****"); } return e; }) .toList()); try { return executeRequest(httpPost); } catch (IOException | URISyntaxException e) { if (e instanceof OAuth2ServiceException oAuth2Exception) throw oAuth2Exception; throw new OAuth2ServiceException("Unexpected error retrieving JWT token: " + e); } } private OAuth2TokenResponse executeRequest(HttpPost httpPost) throws IOException, URISyntaxException { httpPost.addHeader(USER_AGENT, HttpClientUtil.getUserAgent()); URI requestUri = httpPost.getURI(); LOGGER.debug("Requesting access token from url {} with headers {}", requestUri, httpPost.getAllHeaders()); String responseBody = httpClient.execute(httpPost, response -> { int statusCode = response.getStatusLine().getStatusCode(); LOGGER.debug("Received statusCode {}", statusCode); String body = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); if (statusCode != HttpStatus.SC_OK) { LOGGER.debug("Received response body: {}", body); throw OAuth2ServiceException.builder("Error retrieving JWT token") .withStatusCode(statusCode) .withUri(requestUri) .withHeaders(response.getAllHeaders() != null ? Arrays.stream(response.getAllHeaders()).map( Header::toString) .toArray(String[]::new) : null) .withResponseBody(body) .build(); } return body; }); return convertToOAuth2TokenResponse(responseBody); } private OAuth2TokenResponse convertToOAuth2TokenResponse(String responseBody) throws OAuth2ServiceException { Map accessTokenMap = new JSONObject(responseBody).toMap(); String accessToken = getParameter(accessTokenMap, ACCESS_TOKEN); String refreshToken = getParameter(accessTokenMap, REFRESH_TOKEN); String expiresIn = getParameter(accessTokenMap, EXPIRES_IN); String tokenType = getParameter(accessTokenMap, TOKEN_TYPE); return new OAuth2TokenResponse(accessToken, convertExpiresInToLong(expiresIn), refreshToken, tokenType); } private Long convertExpiresInToLong(String expiresIn) throws OAuth2ServiceException { try { return Long.parseLong(expiresIn); } catch (NumberFormatException e) { throw new OAuth2ServiceException( String.format("Cannot convert expires_in from response (%s) to long", expiresIn)); } } private String getParameter(Map accessTokenMap, String key) { return String.valueOf(accessTokenMap.get(key)); } private HttpPost createHttpPost(URI uri, HttpHeaders headers, Map parameters) throws OAuth2ServiceException { HttpPost httpPost = new HttpPost(uri); headers.getHeaders().forEach(header -> httpPost.setHeader(header.getName(), header.getValue())); List basicNameValuePairs = parameters.entrySet().stream() .map(entry -> new BasicNameValuePair(entry.getKey(), entry.getValue())) .toList(); try { httpPost.setEntity(new UrlEncodedFormEntity(basicNameValuePairs)); } catch (UnsupportedEncodingException e) { throw new OAuth2ServiceException("Unexpected error parsing URI: " + e.getMessage()); } return httpPost; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy