Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(frontend): Parse JWT access token claims #5138

Merged
merged 16 commits into from
Jun 13, 2022
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
50 changes: 50 additions & 0 deletions datahub-frontend/app/auth/sso/oidc/OidcAuthorizationGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package auth.sso.oidc;

import java.util.Map.Entry;

import org.pac4j.core.authorization.generator.AuthorizationGenerator;
import org.pac4j.core.context.WebContext;
import org.pac4j.core.profile.AttributeLocation;
import org.pac4j.core.profile.CommonProfile;
import org.pac4j.core.profile.definition.ProfileDefinition;
import org.pac4j.oidc.profile.OidcProfile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.nimbusds.jwt.JWT;
import com.nimbusds.jwt.JWTParser;

public class OidcAuthorizationGenerator implements AuthorizationGenerator {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we name this class to reflect that its related to Parsing access tokens?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can also keep this name, but just pass in the "OidcConfigs" object in the constructor, and then decide whether to parse JWT access tokens inside of here!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passed in OidcConfigs in constructor


private static final Logger logger = LoggerFactory.getLogger(OidcAuthorizationGenerator.class);

private final ProfileDefinition profileDef;

private final OidcConfigs oidcConfigs;

public OidcAuthorizationGenerator(final ProfileDefinition profileDef, final OidcConfigs oidcConfigs) {
this.profileDef = profileDef;
this.oidcConfigs = oidcConfigs;
}

@Override
public CommonProfile generate(WebContext context, CommonProfile profile) {
if (oidcConfigs.getExtractJwtAccessTokenClaims().orElse(false)) {
try {
final JWT jwt = JWTParser.parse(((OidcProfile) profile).getAccessToken().getValue());

for (final Entry<String, Object> entry : jwt.getJWTClaimsSet().getClaims().entrySet()) {
final String claimName = entry.getKey();
if (profile.getAttribute(claimName) == null) {
profileDef.convertAndAdd(profile, AttributeLocation.PROFILE_ATTRIBUTE, claimName, entry.getValue());
}
}
} catch (Exception e) {
logger.warn("Cannot parse access token claims", e);
}
}

return profile;
}

}
3 changes: 3 additions & 0 deletions datahub-frontend/app/auth/sso/oidc/OidcConfigs.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public class OidcConfigs extends SsoConfigs {
public static final String OIDC_USE_NONCE = "auth.oidc.useNonce";
public static final String OIDC_CUSTOM_PARAM_RESOURCE = "auth.oidc.customParam.resource";
public static final String OIDC_READ_TIMEOUT = "auth.oidc.readTimeout";
public static final String OIDC_EXTRACT_JWT_ACCESS_TOKEN_CLAIMS = "auth.oidc.extractJwtAccessTokenClaims";

/**
* Default values
Expand Down Expand Up @@ -69,6 +70,7 @@ public class OidcConfigs extends SsoConfigs {
private Optional<Boolean> useNonce;
private Optional<String> customParamResource;
private String readTimeout;
private Optional<Boolean> extractJwtAccessTokenClaims;

public OidcConfigs(final com.typesafe.config.Config configs) {
super(configs);
Expand All @@ -94,5 +96,6 @@ public OidcConfigs(final com.typesafe.config.Config configs) {
useNonce = getOptional(configs, OIDC_USE_NONCE).map(Boolean::parseBoolean);
customParamResource = getOptional(configs, OIDC_CUSTOM_PARAM_RESOURCE);
readTimeout = getOptional(configs, OIDC_READ_TIMEOUT, DEFAULT_OIDC_READ_TIMEOUT);
extractJwtAccessTokenClaims = getOptional(configs, OIDC_EXTRACT_JWT_ACCESS_TOKEN_CLAIMS).map(Boolean::parseBoolean);
}
}
2 changes: 2 additions & 0 deletions datahub-frontend/app/auth/sso/oidc/OidcProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.pac4j.oidc.config.OidcConfiguration;
import org.pac4j.oidc.credentials.OidcCredentials;
import org.pac4j.oidc.profile.OidcProfile;
import org.pac4j.oidc.profile.OidcProfileDefinition;


/**
Expand Down Expand Up @@ -70,6 +71,7 @@ private Client<OidcCredentials, OidcProfile> createPac4jClient() {
oidcClient.setName(OIDC_CLIENT_NAME);
oidcClient.setCallbackUrl(_oidcConfigs.getAuthBaseUrl() + _oidcConfigs.getAuthBaseCallbackPath());
oidcClient.setCallbackUrlResolver(new PathParameterCallbackUrlResolver());
oidcClient.addAuthorizationGenerator(new OidcAuthorizationGenerator(new OidcProfileDefinition(), _oidcConfigs));
return oidcClient;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import org.pac4j.oidc.profile.creator.OidcProfileCreator;
import org.pac4j.oidc.redirect.OidcRedirectActionBuilder;


public class CustomOidcClient extends OidcClient<OidcProfile, OidcConfiguration> {

public CustomOidcClient(final OidcConfiguration configuration) {
Expand Down
1 change: 1 addition & 0 deletions datahub-frontend/conf/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ auth.oidc.responseMode = ${?AUTH_OIDC_RESPONSE_MODE}
auth.oidc.useNonce = ${?AUTH_OIDC_USE_NONCE}
auth.oidc.customParam.resource = ${?AUTH_OIDC_CUSTOM_PARAM_RESOURCE}
auth.oidc.readTimeout = ${?AUTH_OIDC_READ_TIMEOUT}
auth.oidc.extractJwtAccessTokenClaims = ${?AUTH_OIDC_EXTRACT_JWT_ACCESS_TOKEN_CLAIMS} # Whether to extract claims from JWT access token. Defaults to false.

#
# By default, the callback URL that should be registered with the identity provider is computed as {$baseUrl}/callback/oidc.
Expand Down