Skip to content

Commit

Permalink
Change validation of OIDC token issuer to support parameterized queri…
Browse files Browse the repository at this point in the history
…es (#818)
  • Loading branch information
sp193 authored Dec 6, 2024
1 parent 7c36aaf commit aee82de
Showing 1 changed file with 27 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
import org.forgerock.util.Reject;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Set;

import static org.forgerock.openam.authentication.modules.oidc.OpenIdConnectConfig.*;
Expand Down Expand Up @@ -68,7 +70,7 @@ public JwtClaimsSet validateJwt(String jwtValue) throws AuthLoginException {
final SignedJwt signedJwt = getSignedJwt(jwtValue);
JwtClaimsSet jwtClaimSet = signedJwt.getClaimsSet();
final String jwtClaimSetIssuer = jwtClaimSet.getIssuer();
if (!config.getConfiguredIssuer().equals(jwtClaimSetIssuer)) {
if (!config.getConfiguredIssuer().equals(jwtClaimSetIssuer) && !isJwtFromIssuerFormat(jwtClaimSet)) {
logger.error("The issuer configured for the module, " + config.getConfiguredIssuer() + ", and the " +
"issuer found in the token, " + jwtClaimSetIssuer + ", do not match. This means that the token " +
"authentication was directed at the wrong module, or the targeted module is mis-configured.");
Expand Down Expand Up @@ -136,6 +138,30 @@ public JwtClaimsSet validateJwt(String jwtValue) throws AuthLoginException {
return jwtClaimSet;
}

/**
* Indicates whether the JWT token is issued by configured issuer, with parameterized substitution from the claims set.
* Example: <tt>https://login.microsoftonline.com/{tid}/v2.0</tt> shall have <tt>{tid}</tt> replaced with the iss claim's value.
*
* @param jwtClaimSet The JWT claims.
* @return Whether the JWT token is issued by the configured issuer.
*/
private boolean isJwtFromIssuerFormat(JwtClaimsSet jwtClaimSet) {
/* Since the OpenID Connect Core says "The Issuer Identifier [...] MUST exactly match the value of the iss (issuer) Claim.",
allow only parameterized matching. */
final Matcher m = Pattern.compile("\\{[^\\}]+\\}").matcher(config.getConfiguredIssuer());
final StringBuffer issuer = new StringBuffer();
while (m.find()) {
final String group = m.group();
final String key = group.substring(1, group.length() - 1);
final Object value = jwtClaimSet.getClaim(key);
if (value != null)
m.appendReplacement(issuer, value.toString());
}
m.appendTail(issuer);

return issuer.toString().equals(jwtClaimSet.getIssuer());
}

/**
* Retrieve the actual JWT token from the encoded JWT token.
*
Expand Down

0 comments on commit aee82de

Please sign in to comment.