From 0280563588d98f01bf3fd5b981914194904abe71 Mon Sep 17 00:00:00 2001 From: Justin Field Date: Fri, 16 Apr 2021 09:39:22 -0700 Subject: [PATCH] feat(oauth2): allow extension projects to define a custom function for extracting groups (#1455) --- .../oauth2/SpinnakerUserInfoTokenServices.groovy | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/gate-oauth2/src/main/groovy/com/netflix/spinnaker/gate/security/oauth2/SpinnakerUserInfoTokenServices.groovy b/gate-oauth2/src/main/groovy/com/netflix/spinnaker/gate/security/oauth2/SpinnakerUserInfoTokenServices.groovy index fbbabd15d5..966cfe5152 100644 --- a/gate-oauth2/src/main/groovy/com/netflix/spinnaker/gate/security/oauth2/SpinnakerUserInfoTokenServices.groovy +++ b/gate-oauth2/src/main/groovy/com/netflix/spinnaker/gate/security/oauth2/SpinnakerUserInfoTokenServices.groovy @@ -28,6 +28,7 @@ import com.netflix.spinnaker.security.User import groovy.json.JsonSlurper import groovy.util.logging.Slf4j import org.springframework.beans.factory.annotation.Autowired +import org.springframework.beans.factory.annotation.Qualifier import org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerProperties import org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices import org.springframework.security.authentication.BadCredentialsException @@ -40,6 +41,7 @@ import org.springframework.security.oauth2.provider.token.ResourceServerTokenSer import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken import retrofit.RetrofitError +import java.util.function.BiFunction import java.util.regex.Pattern import java.util.regex.PatternSyntaxException @@ -85,6 +87,10 @@ class SpinnakerUserInfoTokenServices implements ResourceServerTokenServices { @Autowired Registry registry + @Autowired(required = false) + @Qualifier("spinnaker-oauth2-group-extractor") + BiFunction> groupExtractor + RetrySupport retrySupport = new RetrySupport() @Override @@ -108,7 +114,10 @@ class SpinnakerUserInfoTokenServices implements ResourceServerTokenServices { } def username = details[userInfoMapping.username] as String - def roles = getRoles(details) ?: [] + def roles = Optional.ofNullable(groupExtractor) + .map({ extractor -> extractor.apply(accessToken, details) }) + .or({ Optional.ofNullable(getRoles(details)) }) + .orElse([]) // Service accounts are already logged in. if (!isServiceAccount) {