Skip to content

Instantly share code, notes, and snippets.

@mhewedy
Created January 11, 2022 22:46
Show Gist options
  • Save mhewedy/e4e29cbf1b2078125b833a4cd9ef5b45 to your computer and use it in GitHub Desktop.
Save mhewedy/e4e29cbf1b2078125b833a4cd9ef5b45 to your computer and use it in GitHub Desktop.
public class SecurityConfig {
// ......
// userIds claim mapper should be added to keycloak that gets its value from user's attribute with the same name
@Bean
public JwtDecoder customDecoder(OAuth2ResourceServerProperties properties, HttpServletRequest httpServletRequest) {
NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withJwkSetUri(
properties.getJwt().getJwkSetUri()).build();
jwtDecoder.setClaimSetConverter(new ClaimConverter(httpServletRequest));
return jwtDecoder;
}
@RequiredArgsConstructor
private static class ClaimConverter implements Converter<Map<String, Object>, Map<String, Object>> {
private final HttpServletRequest httpServletRequest;
private final MappedJwtClaimSetConverter delegate =
MappedJwtClaimSetConverter.withDefaults(Collections.emptyMap());
public Map<String, Object> convert(Map<String, Object> claims) {
Map<String, Object> convertedClaims = this.delegate.convert(claims);
List<String> userIdsClaim = Optional.ofNullable(convertedClaims.get("userIds"))
.map(Object::toString)
.map(it -> it.split(","))
.map(Arrays::asList)
.orElse(Collections.emptyList());
Object userIdNumber = convertedClaims.get("preferred_username");
if (userIdsClaim.size() == 0) {
throw new IllegalStateException("userIds claim not set for: " + userIdNumber);
}
if (userIdsClaim.size() == 1) {
// in case of only one user id found in the claim, the no need to check the headers and we got this user id from claims
convertedClaims.put("userId", userIdsClaim.get(0));
} else {
String userIdFromHeaders = httpServletRequest.getHeader("X-User-Id");
if (userIdsClaim.contains(userIdFromHeaders)) {
convertedClaims.put("userId", userIdFromHeaders);
} else {
throw new IllegalStateException("userId not found in userIds claim for: " + userIdNumber);
}
}
return convertedClaims;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment