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

Avoid treating IdTokens issued by providers as internal IdTokens #23070

Merged
merged 1 commit into from
Jan 21, 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
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public class CodeAuthenticationMechanism extends AbstractOidcAuthenticationMecha
static final Uni<Void> VOID_UNI = Uni.createFrom().voidItem();
static final Integer MAX_COOKIE_VALUE_LENGTH = 4096;

private static final String INTERNAL_IDTOKEN_HEADER = "internal";
private static final Logger LOG = Logger.getLogger(CodeAuthenticationMechanism.class);

private final BlockingTaskRunner<String> createTokenStateRequestContext = new BlockingTaskRunner<String>();
Expand Down Expand Up @@ -106,7 +107,7 @@ public Uni<? extends SecurityIdentity> apply(AuthorizationCodeTokens session) {
context.put(AuthorizationCodeTokens.class.getName(), session);
return authenticate(identityProviderManager, context,
new IdTokenCredential(session.getIdToken(),
!configContext.oidcConfig.authentication.isIdTokenRequired().orElse(true)))
isInternalIdToken(session.getIdToken(), configContext)))
.call(new Function<SecurityIdentity, Uni<?>>() {
@Override
public Uni<Void> apply(SecurityIdentity identity) {
Expand Down Expand Up @@ -153,9 +154,20 @@ public Uni<? extends SecurityIdentity> apply(Throwable t) {
}
});
}

});
}

private boolean isInternalIdToken(String idToken, TenantConfigContext configContext) {
if (!configContext.oidcConfig.authentication.idTokenRequired.orElse(true)) {
JsonObject headers = OidcUtils.decodeJwtHeaders(idToken);
if (headers != null) {
return headers.getBoolean(INTERNAL_IDTOKEN_HEADER, false);
}
}
return false;
}

private boolean isJavaScript(RoutingContext context) {
String value = context.request().getHeader("X-Requested-With");
return "JavaScript".equals(value) || "XMLHttpRequest".equals(value);
Expand Down Expand Up @@ -361,7 +373,8 @@ public Throwable apply(Throwable tInner) {
}

private String generateInternalIdToken(OidcTenantConfig oidcConfig) {
return Jwt.claims().sign(KeyUtils.createSecretKeyFromSecret(oidcConfig.credentials.secret.get()));
return Jwt.claims().jws().header(INTERNAL_IDTOKEN_HEADER, true)
.sign(KeyUtils.createSecretKeyFromSecret(oidcConfig.credentials.secret.get()));
}

private Uni<Void> processSuccessfulAuthentication(RoutingContext context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,22 @@ public static JsonObject decodeJwtContent(String jwt) {
if (tokens.countTokens() != 1) {
return null;
}
return decodeAsJsonObject(encodedContent);
}

private static JsonObject decodeAsJsonObject(String encodedContent) {
try {
return new JsonObject(new String(Base64.getUrlDecoder().decode(encodedContent), StandardCharsets.UTF_8));
} catch (IllegalArgumentException ex) {
return null;
}
}

public static JsonObject decodeJwtHeaders(String jwt) {
StringTokenizer tokens = new StringTokenizer(jwt, ".");
return decodeAsJsonObject(tokens.nextToken());
}

public static List<String> findRoles(String clientId, OidcTenantConfig.Roles rolesConfig, JsonObject json) {
// If the user configured a specific path - check and enforce a claim at this path exists
if (rolesConfig.getRoleClaimPath().isPresent()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ quarkus.oidc.tenant-web-app-no-discovery.client-id=quarkus-app-webapp
quarkus.oidc.tenant-web-app-no-discovery.credentials.secret=secret
quarkus.oidc.tenant-web-app-no-discovery.application-type=web-app
quarkus.oidc.tenant-web-app-no-discovery.authentication.user-info-required=true
quarkus.oidc.tenant-web-app-no-discovery.authentication.id-token-required=false
quarkus.oidc.tenant-web-app-no-discovery.roles.source=userinfo
quarkus.oidc.tenant-web-app-no-discovery.allow-user-info-cache=false

Expand Down