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

fix(auth): oidc group can be a string #1263

Merged
merged 1 commit into from
Jan 2, 2023
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
6 changes: 5 additions & 1 deletion src/main/java/org/akhq/modules/OidcUserDetailsMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ protected String getUsername(Oidc.Provider provider, OpenIdClaims openIdClaims)

/**
* Tries to read groups from the configured groups field.
* If the configured field cannot be found or isn't some kind of collection, it will return an empty set.
* If the configured field cannot be found or isn't some kind of collection or string, it will return an empty set.
*
* @param provider The OpenID provider configuration
* @param openIdClaims The OpenID claims
Expand All @@ -116,11 +116,15 @@ protected List<String> getOidcGroups(Oidc.Provider provider, OpenIdClaims openId
List<String> groups = new ArrayList<>();
if (openIdClaims.contains(provider.getGroupsField())) {
Object groupsField = openIdClaims.get(provider.getGroupsField());
// When the user belongs to only one group, groupsField can either be an array (with one item)
// or a string, depending on the IdP implementation.
if (groupsField instanceof Collection) {
groups = ((Collection<Object>) groupsField)
.stream()
.map(Objects::toString)
.collect(Collectors.toList());
} else if (groupsField instanceof String) {
groups.add((String) groupsField);
}
}
return groups;
Expand Down
32 changes: 32 additions & 0 deletions src/test/java/org/akhq/modules/OidcAuthenticationProviderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,38 @@ void successSingleOidcGroup() {
assertEquals("test.*", ((List<?>) response.getAuthentication().get().getAttributes().get("topicsFilterRegexp")).get(0));
}

@Test
void successSingleStringOidcGroup() {
JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
.claim(OpenIdClaims.CLAIMS_PREFERRED_USERNAME, "user")
.claim("roles", "oidc-limited-group")
.build();
JWT jwt = new PlainJWT(claimsSet);

Mockito.when(tokenEndpointClient.sendRequest(ArgumentMatchers.any()))
.thenReturn(Publishers.just(new OpenIdTokenResponse()));
Mockito.when(openIdTokenResponseValidator.validate(ArgumentMatchers.any(), ArgumentMatchers.any(), ArgumentMatchers.any(), ArgumentMatchers.any()))
.thenReturn(Optional.of(jwt));

AuthenticationResponse response = Flowable
.fromPublisher(oidcProvider.authenticate(null, new UsernamePasswordCredentials(
"user",
"pass"
))).blockingFirst();

assertTrue(response.isAuthenticated());
assertTrue(response.getAuthentication().isPresent());
assertEquals("user", response.getAuthentication().get().getName());

Collection<String> roles = response.getAuthentication().get().getRoles();

assertThat(roles, hasSize(4));
assertThat(roles, hasItem("topic/read"));
assertThat(roles, hasItem("registry/version/delete"));

assertEquals("test.*", ((List<?>) response.getAuthentication().get().getAttributes().get("topicsFilterRegexp")).get(0));
}

@SuppressWarnings("unchecked")
@Test
void successWithMultipleOidcGroups() {
Expand Down