Skip to content

Commit

Permalink
Both decoders refactored (identical code).
Browse files Browse the repository at this point in the history
  • Loading branch information
rfc3092 committed Feb 27, 2025
1 parent 353c686 commit 5b5957e
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ class MultipleIssuersJwtDecoder implements JwtDecoder {
.stream()
.collect(Collectors.toMap(
ResourceServerProperties::getIssuerUri,
this::getValidatingDecoder
MultipleIssuersJwtDecoder::getValidatingDecoder
));
}

private NimbusJwtDecoder getValidatingDecoder(ResourceServerProperties properties) {
private static NimbusJwtDecoder getValidatingDecoder(ResourceServerProperties properties) {
NimbusJwtDecoder jwtDecoder = JwtDecoders.fromIssuerLocation(properties.getIssuerUri());
jwtDecoder.setJwtValidator(oAuth2TokenValidator(properties));
return jwtDecoder;
Expand Down Expand Up @@ -61,7 +61,7 @@ public Jwt decode(String token) throws JwtException {
}
}

private OAuth2TokenValidator<Jwt> oAuth2TokenValidator(ResourceServerProperties properties) {
private static OAuth2TokenValidator<Jwt> oAuth2TokenValidator(ResourceServerProperties properties) {
return new DelegatingOAuth2TokenValidator<>(
issuerValidator(properties.getIssuerUri()),
audienceValidator(properties.getAcceptedAudience())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,54 +16,76 @@

@Slf4j
class MultipleIssuersJwtDecoder implements JwtDecoder {

private final Map<String, NimbusJwtDecoder> decoderMap;

MultipleIssuersJwtDecoder(List<ResourceServerProperties> properties) {
this.decoderMap = properties.stream().collect(Collectors.toMap(
ResourceServerProperties::getIssuerUri,
props -> {
NimbusJwtDecoder jwtDecoder = JwtDecoders.fromIssuerLocation(props.getIssuerUri());
jwtDecoder.setJwtValidator(oAuth2TokenValidator(props));
return jwtDecoder;
}
));
decoderMap = properties
.stream()
.collect(Collectors.toMap(
ResourceServerProperties::getIssuerUri,
MultipleIssuersJwtDecoder::getValidatingDecoder
));
}

private static NimbusJwtDecoder getValidatingDecoder(ResourceServerProperties properties) {
NimbusJwtDecoder jwtDecoder = JwtDecoders.fromIssuerLocation(properties.getIssuerUri());
jwtDecoder.setJwtValidator(oAuth2TokenValidator(properties));
return jwtDecoder;
}

@Override
public Jwt decode(String token) throws JwtException {
try {

var issuer = JWTParser
.parse(token)
.getJWTClaimsSet()
.getIssuer();
return decoderMap
.get(issuer)
.decode(token);
if (issuer == null || !decoderMap.containsKey(issuer)) {
throw new JwtException("JWT decoder for issuer %s not found".formatted(issuer));
}
var decoder = decoderMap.get(issuer);
log.info("Decoding token with issuer {} using decoder {}", issuer, decoder.getClass().getSimpleName());
return decoder.decode(token);

} catch (ParseException e) {
log.error("Feil ved parsing av token", e);
log.error("Error in offset {} when parsing token", e.getErrorOffset(), e);
throw new JwtException("Feil ved parsing av token", e);
} catch (JwtValidationException e) {
log.error("Feil ved validering av token", e);
log.error("Error(s) validating token: {}", e.getErrors(), e);
throw e;
} catch (Exception e) {
log.error("Ukjent feil", e);
throw e;
log.error("Unexpected failure", e);
throw new JwtException("Unexpected failure", e);
}
}

private OAuth2TokenValidator<Jwt> oAuth2TokenValidator(ResourceServerProperties properties) {
OAuth2TokenValidator<Jwt> issuerValidator = JwtValidators.createDefaultWithIssuer(properties.getIssuerUri());
OAuth2TokenValidator<Jwt> audienceValidator = token ->
token.getAudience().stream().anyMatch(audience -> properties.getAcceptedAudience().contains(audience)) ?
OAuth2TokenValidatorResult.success() :
OAuth2TokenValidatorResult.failure(createError(
String.format("Fant ikke påkrevd audience %s i tokenet.", properties.getAcceptedAudience())
));
return new DelegatingOAuth2TokenValidator<>(issuerValidator, audienceValidator);
private static OAuth2TokenValidator<Jwt> oAuth2TokenValidator(ResourceServerProperties properties) {
return new DelegatingOAuth2TokenValidator<>(
issuerValidator(properties.getIssuerUri()),
audienceValidator(properties.getAcceptedAudience())
);
}

private static OAuth2TokenValidator<Jwt> issuerValidator(String issuerUri) {
return JwtValidators.createDefaultWithIssuer(issuerUri); // Note that this creates and adds a default audience validator.
}

private OAuth2Error createError(String msg) {
return new OAuth2Error("invalid_token", msg, null);
private static OAuth2TokenValidator<Jwt> audienceValidator(List<String> acceptedAudience) {
return token -> {
var audience = token.getAudience();
var audienceIsAccepted = audience
.stream()
.anyMatch(acceptedAudience::contains);
if (audienceIsAccepted) {
log.info("Token audience {} is accepted by {}", audience, acceptedAudience);
return OAuth2TokenValidatorResult.success();
}
var message = "Token audience %s is not accepted by %s".formatted(audience, acceptedAudience);
log.warn(message);
return OAuth2TokenValidatorResult.failure(new OAuth2Error("invalid_token", message, null));
};
}

}

0 comments on commit 5b5957e

Please sign in to comment.