-
Notifications
You must be signed in to change notification settings - Fork 114
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Read groups claim from token (#1207)
- Loading branch information
1 parent
4117433
commit e61acbf
Showing
4 changed files
with
96 additions
and
84 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
...ain/java/org/opendatadiscovery/oddplatform/auth/handler/impl/AbstractOIDCUserHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package org.opendatadiscovery.oddplatform.auth.handler.impl; | ||
|
||
import com.nimbusds.jose.shaded.json.JSONArray; | ||
import java.util.Objects; | ||
import java.util.Set; | ||
import lombok.RequiredArgsConstructor; | ||
import org.apache.commons.collections4.CollectionUtils; | ||
import org.apache.commons.lang3.StringUtils; | ||
import org.opendatadiscovery.oddplatform.auth.ODDOAuth2Properties; | ||
import org.opendatadiscovery.oddplatform.auth.handler.OAuthUserHandler; | ||
import org.opendatadiscovery.oddplatform.auth.mapper.GrantedAuthorityExtractor; | ||
import org.springframework.security.core.GrantedAuthority; | ||
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest; | ||
import org.springframework.security.oauth2.core.oidc.OidcIdToken; | ||
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; | ||
import org.springframework.security.oauth2.core.oidc.user.OidcUser; | ||
import reactor.core.publisher.Mono; | ||
|
||
import static org.opendatadiscovery.oddplatform.utils.OperationUtils.containsIgnoreCase; | ||
|
||
@RequiredArgsConstructor | ||
public abstract class AbstractOIDCUserHandler implements OAuthUserHandler<OidcUser, OidcUserRequest> { | ||
private final ODDOAuth2Properties oAuth2Properties; | ||
private final GrantedAuthorityExtractor authorityExtractor; | ||
|
||
@Override | ||
public Mono<OidcUser> enrichUserWithProviderInformation(final OidcUser oidcUser, final OidcUserRequest request) { | ||
final String registrationId = request.getClientRegistration().getRegistrationId(); | ||
final ODDOAuth2Properties.OAuth2Provider provider = oAuth2Properties.getClient().get(registrationId); | ||
final String userNameAttributeName = provider.getUserNameAttribute(); | ||
final String userNameAttribute = | ||
Objects.requireNonNullElse(userNameAttributeName, getDefaultUsernameAttribute()); | ||
boolean isAdmin = false; | ||
final OidcIdToken token = oidcUser.getIdToken(); | ||
if (CollectionUtils.isNotEmpty(provider.getAdminPrincipals())) { | ||
final String adminPrincipalAttribute = StringUtils.isNotEmpty(provider.getAdminAttribute()) | ||
? provider.getAdminAttribute() : userNameAttributeName; | ||
final String adminAttribute = token.getClaim(adminPrincipalAttribute); | ||
final boolean containsUsername = containsIgnoreCase(provider.getAdminPrincipals(), adminAttribute); | ||
if (containsUsername) { | ||
isAdmin = true; | ||
} | ||
} | ||
final String groupsClaim = StringUtils.isNotEmpty(provider.getGroupsClaim()) | ||
? provider.getGroupsClaim() : getDefaultGroupsClaim(); | ||
if (StringUtils.isNotEmpty(groupsClaim) && CollectionUtils.isNotEmpty(provider.getAdminGroups())) { | ||
final JSONArray groups = token.getClaim(groupsClaim); | ||
if (groups != null) { | ||
final boolean containsGroup = groups.stream() | ||
.filter(String.class::isInstance) | ||
.map(String.class::cast) | ||
.anyMatch(g -> containsIgnoreCase(provider.getAdminGroups(), g)); | ||
if (containsGroup) { | ||
isAdmin = true; | ||
} | ||
} | ||
} | ||
final Set<GrantedAuthority> authorities = authorityExtractor.getAuthorities(isAdmin); | ||
final DefaultOidcUser enrichedUser = | ||
new DefaultOidcUser(authorities, oidcUser.getIdToken(), oidcUser.getUserInfo(), userNameAttribute); | ||
return Mono.just(enrichedUser); | ||
} | ||
|
||
protected abstract String getDefaultUsernameAttribute(); | ||
|
||
protected abstract String getDefaultGroupsClaim(); | ||
} |
64 changes: 14 additions & 50 deletions
64
...src/main/java/org/opendatadiscovery/oddplatform/auth/handler/impl/CognitoUserHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,74 +1,38 @@ | ||
package org.opendatadiscovery.oddplatform.auth.handler.impl; | ||
|
||
import com.nimbusds.jose.shaded.json.JSONArray; | ||
import java.util.Objects; | ||
import java.util.Set; | ||
import lombok.RequiredArgsConstructor; | ||
import org.apache.commons.collections4.CollectionUtils; | ||
import org.apache.commons.lang3.StringUtils; | ||
import org.opendatadiscovery.oddplatform.auth.ODDOAuth2Properties; | ||
import org.opendatadiscovery.oddplatform.auth.Provider; | ||
import org.opendatadiscovery.oddplatform.auth.condition.CognitoCondition; | ||
import org.opendatadiscovery.oddplatform.auth.handler.OAuthUserHandler; | ||
import org.opendatadiscovery.oddplatform.auth.mapper.GrantedAuthorityExtractor; | ||
import org.springframework.context.annotation.Conditional; | ||
import org.springframework.security.core.GrantedAuthority; | ||
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest; | ||
import org.springframework.security.oauth2.core.oidc.OidcIdToken; | ||
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; | ||
import org.springframework.security.oauth2.core.oidc.user.OidcUser; | ||
import org.springframework.stereotype.Component; | ||
import reactor.core.publisher.Mono; | ||
|
||
import static org.opendatadiscovery.oddplatform.utils.OperationUtils.containsIgnoreCase; | ||
|
||
@Component | ||
@Conditional(CognitoCondition.class) | ||
@RequiredArgsConstructor | ||
public class CognitoUserHandler implements OAuthUserHandler<OidcUser, OidcUserRequest> { | ||
private static final String COGNITO_USERNAME = "cognito:username"; | ||
private static final String COGNITO_GROUPS = "cognito:groups"; | ||
private final GrantedAuthorityExtractor authorityExtractor; | ||
private final ODDOAuth2Properties oAuth2Properties; | ||
public class CognitoUserHandler extends AbstractOIDCUserHandler | ||
implements OAuthUserHandler<OidcUser, OidcUserRequest> { | ||
|
||
public CognitoUserHandler(final ODDOAuth2Properties properties, | ||
final GrantedAuthorityExtractor authorityExtractor) { | ||
super(properties, authorityExtractor); | ||
} | ||
|
||
@Override | ||
public boolean shouldHandle(final String provider) { | ||
return StringUtils.isNotEmpty(provider) && provider.equalsIgnoreCase(Provider.COGNITO.name()); | ||
} | ||
|
||
@Override | ||
public Mono<OidcUser> enrichUserWithProviderInformation(final OidcUser oidcUser, | ||
final OidcUserRequest request) { | ||
final String registrationId = request.getClientRegistration().getRegistrationId(); | ||
final ODDOAuth2Properties.OAuth2Provider provider = oAuth2Properties.getClient().get(registrationId); | ||
boolean isAdmin = false; | ||
final OidcIdToken token = oidcUser.getIdToken(); | ||
if (CollectionUtils.isNotEmpty(provider.getAdminPrincipals())) { | ||
final String adminPrincipalAttribute = StringUtils.isNotEmpty(provider.getAdminAttribute()) | ||
? provider.getAdminAttribute() : COGNITO_USERNAME; | ||
final String username = token.getClaim(adminPrincipalAttribute); | ||
final boolean containsUsername = containsIgnoreCase(provider.getAdminPrincipals(), username); | ||
if (containsUsername) { | ||
isAdmin = true; | ||
} | ||
} | ||
if (CollectionUtils.isNotEmpty(provider.getAdminGroups())) { | ||
final JSONArray groups = token.getClaim(COGNITO_GROUPS); | ||
if (groups != null) { | ||
final boolean containsGroup = groups.stream() | ||
.filter(String.class::isInstance) | ||
.map(String.class::cast) | ||
.anyMatch(g -> containsIgnoreCase(provider.getAdminGroups(), g)); | ||
if (containsGroup) { | ||
isAdmin = true; | ||
} | ||
} | ||
} | ||
final Set<GrantedAuthority> authorities = authorityExtractor.getAuthorities(isAdmin); | ||
final String userNameAttributeName = provider.getUserNameAttribute(); | ||
final String userNameAttribute = Objects.requireNonNullElse(userNameAttributeName, COGNITO_USERNAME); | ||
final DefaultOidcUser enrichedUser = | ||
new DefaultOidcUser(authorities, oidcUser.getIdToken(), oidcUser.getUserInfo(), userNameAttribute); | ||
return Mono.just(enrichedUser); | ||
protected String getDefaultUsernameAttribute() { | ||
return "cognito:username"; | ||
} | ||
|
||
@Override | ||
protected String getDefaultGroupsClaim() { | ||
return "cognito:groups"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters