Skip to content

Commit

Permalink
refactor: rework to include class instantiation for oidcclient and ca…
Browse files Browse the repository at this point in the history
…che json from well known endpoint
  • Loading branch information
at88mph committed Oct 1, 2024
1 parent bfacd4f commit c77d976
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 42 deletions.
68 changes: 37 additions & 31 deletions cadc-gms/src/main/java/org/opencadc/auth/OIDCClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@


/**
* Client to the currently configured OpenID Connect provider.
* Client to the currently configured OpenID Connect provider. This Client class is intended to have a very short lifespan.
* TODO: Generic enough to be more central?
*
* @see LocalAuthority for configuration
Expand All @@ -94,55 +94,61 @@ class OIDCClient {
private static final String USERINFO_ENDPOINT_KEY = "userinfo_endpoint";
private static final String ISSUER_LOOKUP_KEY = Standards.SECURITY_METHOD_OPENID.toASCIIString();

// Cached Well Known JSON. Instances of this class should not linger as this field is not managed and only set once.
private JSONObject wellKnownJSON;

final URI issuer;


/**
* Obtain the Issuer base URL.
*
* @return URL of the Issuer. Never null.
* Public constructor.
* @param issuer The URI of the OpenID Connect Provider. Must be URL compatible.
*/
static URI getIssuerID() {
final LocalAuthority localAuthority = new LocalAuthority();
return localAuthority.getServiceURI(OIDCClient.ISSUER_LOOKUP_KEY);
public OIDCClient(URI issuer) {
this.issuer = issuer;
}

/**
* Obtain the Issuer base URL.
* Obtain the Issuer base URL. Mainly used to validate this as a URL.
*
* @return URL of the Issuer. Never null.
* @throws InvalidConfigException If the configured Issuer URL is not a valid URL.
*/
static URL getIssuer() {
final URI openIDIssuerURI = OIDCClient.getIssuerID();
URL getIssuerURL() {
try {
return openIDIssuerURI.toURL();
return this.issuer.toURL();
} catch (MalformedURLException ex) {
throw new InvalidConfigException("found " + OIDCClient.ISSUER_LOOKUP_KEY + " = " + openIDIssuerURI + " - expected valid URL", ex);
throw new InvalidConfigException("found " + OIDCClient.ISSUER_LOOKUP_KEY + " = " + this.issuer + " - expected valid URL", ex);
}
}

/**
* Obtain the .well-known endpoint JSON document.
* TODO: Cache this?
* Obtain the .well-known endpoint JSON document. This does very simple caching so as to ensure a single read of the well-known endpoint per request.
*
* @return The JSON Object of the response data.
* @throws MalformedURLException If URLs cannot be created as expected.
*/
static JSONObject getWellKnownJSON() throws MalformedURLException {
final URL oidcIssuer = OIDCClient.getIssuer();
final URL configurationURL = new URL(oidcIssuer.toExternalForm() + OIDCClient.WELL_KNOWN_ENDPOINT);
final Writer writer = new StringWriter();
final HttpGet httpGet = new HttpGet(configurationURL, inputStream -> {
final Reader inputReader = new BufferedReader(new InputStreamReader(inputStream));
final char[] buffer = new char[8192];
int charsRead;
while ((charsRead = inputReader.read(buffer)) >= 0) {
writer.write(buffer, 0, charsRead);
}
writer.flush();
});
JSONObject getWellKnownJSON() throws MalformedURLException {
if (this.wellKnownJSON == null) {
final URL oidcIssuer = getIssuerURL();
final URL configurationURL = new URL(oidcIssuer.toExternalForm() + OIDCClient.WELL_KNOWN_ENDPOINT);
final Writer writer = new StringWriter();
final HttpGet httpGet = new HttpGet(configurationURL, inputStream -> {
final Reader inputReader = new BufferedReader(new InputStreamReader(inputStream));
final char[] buffer = new char[8192];
int charsRead;
while ((charsRead = inputReader.read(buffer)) >= 0) {
writer.write(buffer, 0, charsRead);
}
writer.flush();
});

httpGet.run();

httpGet.run();
this.wellKnownJSON = new JSONObject(writer.toString());
}

return new JSONObject(writer.toString());
return this.wellKnownJSON;
}

/**
Expand All @@ -151,8 +157,8 @@ static JSONObject getWellKnownJSON() throws MalformedURLException {
* @return URL of the User Info Endpoint to validate a bearer token. Never null.
* @throws MalformedURLException For a poorly formed URL.
*/
static URL getUserInfoEndpoint() throws MalformedURLException {
final JSONObject jsonObject = OIDCClient.getWellKnownJSON();
URL getUserInfoEndpoint() throws MalformedURLException {
final JSONObject jsonObject = getWellKnownJSON();
final String userInfoEndpointString = jsonObject.getString(OIDCClient.USERINFO_ENDPOINT_KEY);
return new URL(userInfoEndpointString);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,9 @@ public class StandardIdentityManager implements IdentityManager {
tmp.add(Standards.SECURITY_METHOD_TOKEN);
SEC_METHODS = Collections.unmodifiableSet(tmp);
}
private final URI oidcIssuer;

private final OIDCClient oidcClient;

// need these to construct an AuthorizationToken
private final RegistryClient reg = new RegistryClient();
private final List<String> oidcDomains = new ArrayList<>();
Expand All @@ -129,8 +129,9 @@ public class StandardIdentityManager implements IdentityManager {
public StandardIdentityManager() {
LocalAuthority loc = new LocalAuthority();
String key = Standards.SECURITY_METHOD_OPENID.toASCIIString();
this.oidcIssuer = OIDCClient.getIssuerID();
URL u = OIDCClient.getIssuer();
oidcClient = new OIDCClient(loc.getServiceURI(key));

URL u = oidcClient.getIssuerURL();
oidcDomains.add(u.getHost());

// add known and assume trusted A&A services
Expand Down Expand Up @@ -310,9 +311,9 @@ private void validateOidcAccessToken(Subject s) {
log.debug("validateOidcAccessToken - START");
Set<AuthorizationTokenPrincipal> rawTokens = s.getPrincipals(AuthorizationTokenPrincipal.class);

log.debug("token issuer: " + oidcIssuer + " rawTokens: " + rawTokens.size());
if (oidcIssuer != null && !rawTokens.isEmpty()) {
URL u = StandardIdentityManager.getUserEndpoint();
log.debug("token issuer: " + oidcClient.issuer + " rawTokens: " + rawTokens.size());
if (!rawTokens.isEmpty()) {
URL u = getUserEndpoint();
for (AuthorizationTokenPrincipal raw : rawTokens) {
String credentials = null;
String challengeType = null;
Expand Down Expand Up @@ -347,7 +348,7 @@ private void validateOidcAccessToken(Subject s) {
String username = json.getString("preferred_username");
// TODO: register an X509 DN with IAM and see if I can get it back here

OpenIdPrincipal oip = new OpenIdPrincipal(oidcIssuer.toURL(), sub);
OpenIdPrincipal oip = new OpenIdPrincipal(oidcClient.getIssuerURL(), sub);
HttpPrincipal hp = new HttpPrincipal(username);

s.getPrincipals().remove(raw);
Expand Down Expand Up @@ -378,9 +379,9 @@ private void validateOidcAccessToken(Subject s) {
}
}

private static URL getUserEndpoint() {
private URL getUserEndpoint() {
try {
return OIDCClient.getUserInfoEndpoint();
return oidcClient.getUserInfoEndpoint();
} catch (MalformedURLException ex) {
throw new RuntimeException("BUG: failed to create valid oidc userinfo url", ex);
}
Expand Down

0 comments on commit c77d976

Please sign in to comment.