Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -37,33 +37,31 @@
/**
* Suitable only for CWBI Keycloaks direct grant setup.
*/
public final class CwbiAuthTokenProvider extends CwbiAuthTokenProviderBase {
public final class CwbiAuthTokenProvider extends OidcAuthTokenProvider {

private final SSLSocketFactory sslSocketFactory;

/**
* Provider for OAuth2Tokens.
*
* @param wellKnownUrl - URL we are retrieving configuration from
* @param wellKnownUrl - URL we are retrieving configuration from. Note this should include the SSLSocketData if the accessing the well-known endpoint requires client cert auth
* @param clientId - client name
* @param sslSocketFactory - ssl socket factory
*/
public CwbiAuthTokenProvider(String wellKnownUrl, String clientId, SSLSocketFactory sslSocketFactory) {
public CwbiAuthTokenProvider(ApiConnectionInfo wellKnownUrl, String clientId, SSLSocketFactory sslSocketFactory) {
super(clientId, wellKnownUrl);
this.sslSocketFactory = Objects.requireNonNull(sslSocketFactory, "Missing required sslSocketFactory");
}

@Override
ApiConnectionInfo getUrl() {
return new ApiConnectionInfoBuilder(this.wellKnownUrl)
.withSslSocketData(new SslSocketData(sslSocketFactory, CwbiAuthTrustManager.getTrustManager()))
.build();
}

@Override
public ApiConnectionInfo getAuthUrl() {
// This is specific to CWBI Direct Grant so this replacement as-is is fine
return new ApiConnectionInfoBuilder(this.tokenUrl.getApiRoot().replace("identity", "identityc"))
ApiConnectionInfo tokenUrl = this.getTokenUrl();
String apiRoot = tokenUrl.getApiRoot();
if(!apiRoot.contains("identityc")) {
apiRoot = tokenUrl.getApiRoot().replace("identity", "identityc");
}
return new ApiConnectionInfoBuilder(apiRoot)
.withSslSocketData(new SslSocketData(sslSocketFactory, CwbiAuthTrustManager.getTrustManager()))
.build();
}
Expand All @@ -72,7 +70,7 @@ public ApiConnectionInfo getAuthUrl() {
public OAuth2Token newToken() throws IOException {
return new DirectGrantX509TokenRequestBuilder()
.withTokenUrl(getAuthUrl())
.buildRequest().withClientId(clientId)
.buildRequest().withClientId(getClientId())
.fetchToken();
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import java.util.function.Consumer;

import mil.army.usace.hec.cwms.http.client.ApiConnectionInfo;
import mil.army.usace.hec.cwms.http.client.ApiConnectionInfoBuilder;
import mil.army.usace.hec.cwms.http.client.auth.OAuth2Token;
import mil.army.usace.hec.cwms.http.client.auth.OAuth2TokenProvider;

Expand All @@ -20,37 +19,20 @@
*/
public class OidcAuthTokenProvider implements OAuth2TokenProvider {

protected final String clientId;
protected final String wellKnownUrl;
protected final ApiConnectionInfo tokenUrl;
protected final ApiConnectionInfo authUrl;
protected OAuth2Token token = null;
private final String clientId;
private final ApiConnectionInfo wellKnownUrl;
private ApiConnectionInfo tokenUrl;
private ApiConnectionInfo authUrl;
private final StaticOidcTokenController wellKnowEndpointController;
private OAuth2Token token = null;
// Default to open browser or print to console for usage, but allow overriding for testing and
// other usages.
private Consumer<URI> authCallback = TokenRequestBuilder.BROWSER_OR_CONSOLE_AUTH_CALLBACK;

public OidcAuthTokenProvider(String clientId, String wellKnownUrl) {
public OidcAuthTokenProvider(String clientId, ApiConnectionInfo wellKnownUrl) {
this.clientId = Objects.requireNonNull(clientId, "Missing required client id.");
this.wellKnownUrl = Objects.requireNonNull(wellKnownUrl, "Missing required well known Url.");

OpenIdTokenController controller = new OpenIdTokenController() {

@Override
public String retrieveWellKnownEndpoint(ApiConnectionInfo apiConnectionInfo) throws IOException {
return wellKnownUrl; // we already have it.
}

};
ApiConnectionInfo info = new ApiConnectionInfoBuilder(wellKnownUrl).build();
String what = "auth";
try {
this.authUrl = controller.retrieveAuthUrl(info, null);
what = "token";
this.tokenUrl = controller.retrieveTokenUrl(info, null);
// TODO: process appropriate extensions to determine things like "kc_idp_hint"
} catch (IOException ex) {
throw new CompletionException("Unable to return " + what + " URL", ex);
}
this.wellKnowEndpointController = new StaticOidcTokenController(wellKnownUrl);
}

@Override
Expand Down Expand Up @@ -83,12 +65,11 @@ public OAuth2Token getToken() throws IOException {
@Override
public OAuth2Token refreshToken() throws IOException {
synchronized (this) {
OAuth2Token newToken = new RefreshTokenRequestBuilder()
token = new RefreshTokenRequestBuilder()
.withRefreshToken(token.getRefreshToken())
.withUrl(tokenUrl)
.withUrl(getTokenUrl())
.withClientId(clientId)
.fetchToken();
token = newToken;
return token;
}
}
Expand All @@ -102,8 +83,8 @@ public OAuth2Token newToken() throws IOException {
* There are various notes about it in different sections for discussion.
*/
token = new AuthCodePkceTokenRequestBuilder()
.withAuthUrl(authUrl)
.withTokenUrl(tokenUrl)
.withAuthUrl(getAuthUrl())
.withTokenUrl(getTokenUrl())
.withAuthCallback(authCallback)
.buildRequest()
.withClientId(clientId)
Expand All @@ -115,12 +96,38 @@ public OAuth2Token newToken() throws IOException {

@Override
public ApiConnectionInfo getAuthUrl() {
if(authUrl == null) {
initializeAuthUrls();
}
return authUrl;
}

@Override
public ApiConnectionInfo getTokenUrl() {
if(tokenUrl == null) {
initializeAuthUrls();
}
return tokenUrl;
}

private synchronized void initializeAuthUrls() {
String what = "auth";
try {
this.authUrl = this.wellKnowEndpointController.retrieveAuthUrl(wellKnownUrl);
what = "token";
this.tokenUrl = this.wellKnowEndpointController.retrieveTokenUrl(wellKnownUrl);
// TODO: process appropriate extensions to determine things like "kc_idp_hint"
} catch (IOException ex) {
throw new CompletionException("Unable to return " + what + " URL", ex);
}
}

ApiConnectionInfo getWellKnownUrl() {
return this.wellKnownUrl;
}

String getClientId() {
return this.clientId;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import mil.army.usace.hec.cwms.http.client.ApiConnectionInfoBuilder;
import mil.army.usace.hec.cwms.http.client.HttpRequestBuilderImpl;
import mil.army.usace.hec.cwms.http.client.HttpRequestResponse;
import mil.army.usace.hec.cwms.http.client.SslSocketData;
import mil.army.usace.hec.cwms.http.client.request.HttpRequestExecutor;

public abstract class OpenIdTokenController {
Expand All @@ -42,45 +41,37 @@ public abstract class OpenIdTokenController {

/**
* Retrieve json text of the .wellknown/openid-configuration
* @param apiConnectionInfo
* @return
* @throws IOException
* @param apiConnectionInfo - connection info to the config endpoint containing the well-known endpoint
* @return ApiConnectionInfo containing the well-known endpoint url
* @throws IOException - throws IOException if there is an issue with the http request to the config endpoint
*/
public abstract String retrieveWellKnownEndpoint(ApiConnectionInfo apiConnectionInfo) throws IOException;
public abstract ApiConnectionInfo retrieveWellKnownEndpoint(ApiConnectionInfo apiConnectionInfo) throws IOException;

public final ApiConnectionInfo retrieveTokenUrl(ApiConnectionInfo apiConnectionInfo, SslSocketData sslSocketData) throws IOException {
public final ApiConnectionInfo retrieveTokenUrl(ApiConnectionInfo apiConnectionInfo) throws IOException {
if (tokenEndpoint == null) {
String wellKnownEndpoint = retrieveWellKnownEndpoint(apiConnectionInfo);
ApiConnectionInfo wellKnownApiConnectionInfo = retrieveWellKnownEndpoint(apiConnectionInfo);

ApiConnectionInfo wellKnownApiConnectionInfo = new ApiConnectionInfoBuilder(wellKnownEndpoint)
.withSslSocketData(sslSocketData)
.build();
HttpRequestExecutor executor = new HttpRequestBuilderImpl(wellKnownApiConnectionInfo)
.get();
try (HttpRequestResponse response = executor.execute()) {
tokenEndpoint = OAuth2ObjectMapper.getValueForKey(response.getBody(), TOKEN_ENDPOINT_KEY);
}
}
return new ApiConnectionInfoBuilder(tokenEndpoint)
.withSslSocketData(sslSocketData)
.build();
}

public final ApiConnectionInfo retrieveAuthUrl(ApiConnectionInfo apiConnectionInfo, SslSocketData sslSocketData) throws IOException {
public final ApiConnectionInfo retrieveAuthUrl(ApiConnectionInfo apiConnectionInfo) throws IOException {

if (authEndpoint == null) {
String wellKnownEndpoint = retrieveWellKnownEndpoint(apiConnectionInfo);
ApiConnectionInfo wellKnownApiConnectionInfo = new ApiConnectionInfoBuilder(wellKnownEndpoint)
.withSslSocketData(sslSocketData)
.build();
ApiConnectionInfo wellKnownApiConnectionInfo = retrieveWellKnownEndpoint(apiConnectionInfo);
HttpRequestExecutor executor = new HttpRequestBuilderImpl(wellKnownApiConnectionInfo)
.get();
try (HttpRequestResponse response = executor.execute()) {
authEndpoint = OAuth2ObjectMapper.getValueForKey(response.getBody(), AUTH_ENDPOINT_KEY);
}
}
return new ApiConnectionInfoBuilder(authEndpoint)
.withSslSocketData(sslSocketData)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package hec.army.usace.hec.cwbi.auth.http.client;

import mil.army.usace.hec.cwms.http.client.ApiConnectionInfo;
import mil.army.usace.hec.cwms.http.client.ApiConnectionInfoBuilder;
import mil.army.usace.hec.cwms.http.client.SslSocketData;

import java.io.IOException;

/**
* An extension of OpenIdTokenController that allows for SSL socket data to be included in the retrieval of the well-known endpoint.
* This is necessary for cases where the well-known endpoint requires client certificate authentication.
*/
public abstract class SSLOidcDiscoveryController extends OpenIdTokenController {

private final SslSocketData sslSocketData;

protected SSLOidcDiscoveryController(SslSocketData sslSocketData) {
this.sslSocketData = sslSocketData;
}

protected abstract String retrieveWellKnownEndpointUrl(ApiConnectionInfo apiConnectionInfo) throws IOException;

@Override
public final ApiConnectionInfo retrieveWellKnownEndpoint(ApiConnectionInfo apiConnectionInfo) throws IOException {
return new ApiConnectionInfoBuilder(retrieveWellKnownEndpointUrl(apiConnectionInfo))
.withSslSocketData(sslSocketData)
.build();
}
}
Loading
Loading