
com.dnastack.audit.client.AuthHttpClient Maven / Gradle / Ivy
package com.dnastack.audit.client;
import brave.Tracing;
import com.dnastack.audit.ObjectMapperFactory;
import com.dnastack.audit.exception.InvalidTokenResponseException;
import com.dnastack.audit.model.AuditEventLoggerConfig;
import com.dnastack.audit.model.TokenResponse;
import com.dnastack.auth.PermissionChecker;
import com.dnastack.auth.PermissionCheckerFactory;
import com.dnastack.auth.exception.HttpRequestFailedException;
import com.dnastack.auth.keyresolver.CachingIssuerPubKeyJwksResolver;
import com.dnastack.auth.model.IssuerInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static java.lang.String.format;
public class AuthHttpClient {
private final HttpClient httpClient;
private final ObjectMapper objectMapper;
private final AuditEventLoggerConfig.OAuthClient oAuthClientConfig;
private final PermissionChecker permissionChecker;
public AuthHttpClient(AuditEventLoggerConfig.OAuthClient oAuthClientConfig, Tracing tracing) {
this.httpClient = HttpClient.newHttpClient();
this.objectMapper = ObjectMapperFactory.create();
this.oAuthClientConfig = oAuthClientConfig;
final List allowedIssuers = oAuthClientConfig.getTokenIssuersUris().stream()
.distinct()
.map(issuerUri -> IssuerInfo.IssuerInfoBuilder.builder()
.issuerUri(issuerUri)
.allowedAudiences(List.of(oAuthClientConfig.getAudience()))
.publicKeyResolver(new CachingIssuerPubKeyJwksResolver(issuerUri))
.build()).collect(Collectors.toList());
String policyEvaluationRequester = oAuthClientConfig.getPolicyEvaluationRequester();
String policyEvaluationUri = oAuthClientConfig.getPolicyEvaluationUri();
this.permissionChecker = PermissionCheckerFactory.create(allowedIssuers, policyEvaluationRequester, policyEvaluationUri, tracing);
}
public TokenResponse getTokenResponse() {
final String credentials = format("%s:%s", oAuthClientConfig.getClientId(), oAuthClientConfig.getClientSecret());
final String authHeader = format("Basic %s", Base64.getEncoder().encodeToString(credentials.getBytes()));
final URI uri = URI.create(format("%s?grant_type=client_credentials&resource=%s&scope=%s",
oAuthClientConfig.getTokenUri(),
oAuthClientConfig.getResource(),
oAuthClientConfig.getScopes())
);
final HttpRequest request = HttpRequest.newBuilder()
.uri(uri)
.header("Authorization", authHeader)
.POST(HttpRequest.BodyPublishers.noBody())
.build();
return getAndValidateResponse(request);
}
private TokenResponse getAndValidateResponse(HttpRequest request) {
final Map response = sendAndReceive(request, Map.class);
if (response != null && response.containsKey("access_token")) {
final TokenResponse tokenResponse = objectMapper.convertValue(response, TokenResponse.class);
permissionChecker.checkPermissions(tokenResponse.getAccessToken(),
Arrays.asList(oAuthClientConfig.getScopes().split(" ")),
Map.of(oAuthClientConfig.getResource(), oAuthClientConfig.getActions())
);
return tokenResponse;
} else {
throw new InvalidTokenResponseException(format("Expected token response instead got response %s", response));
}
}
protected T sendAndReceive(HttpRequest request, Class responseType) {
try {
final HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
return objectMapper.readValue(response.body(), responseType);
} catch (IOException | InterruptedException ex) {
throw new HttpRequestFailedException(format("Failed request %s %s", request.method(), request.uri()), ex);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy