|
10 | 10 | import java.util.Arrays; |
11 | 11 | import java.util.Collection; |
12 | 12 | import java.util.Collections; |
| 13 | +import java.util.HashSet; |
13 | 14 | import java.util.List; |
14 | 15 | import java.util.Map; |
15 | 16 | import java.util.Set; |
16 | 17 | import java.util.stream.Collectors; |
17 | 18 | import lombok.extern.slf4j.Slf4j; |
| 19 | +import org.springframework.security.core.GrantedAuthority; |
18 | 20 | import org.springframework.security.oauth2.core.user.DefaultOAuth2User; |
19 | 21 | import org.springframework.util.Assert; |
20 | 22 | import reactor.core.publisher.Mono; |
@@ -72,32 +74,48 @@ private Set<String> extractRoles(AccessControlService acs, DefaultOAuth2User pri |
72 | 74 | Map<String, Object> additionalParams) { |
73 | 75 | var provider = (OAuthProperties.OAuth2Provider) additionalParams.get("provider"); |
74 | 76 | Assert.notNull(provider, "provider is null"); |
| 77 | + |
75 | 78 | var rolesFieldName = provider.getCustomParams().get(ROLES_FIELD_PARAM_NAME); |
76 | 79 |
|
| 80 | + Set<String> roles = new HashSet<>(); |
77 | 81 | if (rolesFieldName == null) { |
78 | | - log.warn("Provider [{}] doesn't contain a roles field param name, won't map roles", provider.getClientName()); |
79 | | - return Collections.emptySet(); |
| 82 | + log.warn("Provider [{}] doesn't contain a roles field param name, using default authorities/scopes for role mapping", provider.getClientName()); |
| 83 | + } else { |
| 84 | + var principalRoles = convertRoles(principal.getAttribute(rolesFieldName)); |
| 85 | + |
| 86 | + if (principalRoles.isEmpty()) { |
| 87 | + log.debug("Principal [{}] doesn't have any roles through configured roles-field, using default authorities", principal.getName()); |
| 88 | + } else { |
| 89 | + log.debug("Token's groups: [{}]. Mapping providers of type role.", String.join(",", principalRoles)); |
| 90 | + roles.addAll(acs.getRoles().stream() |
| 91 | + .filter(role -> role.getSubjects() |
| 92 | + .stream() |
| 93 | + .filter(s -> s.getProvider().equals(Provider.OAUTH)) |
| 94 | + .filter(s -> s.getType().equals("role")) |
| 95 | + .anyMatch(subject -> principalRoles.stream().anyMatch(subject::matches))) |
| 96 | + .map(Role::getName) |
| 97 | + .collect(Collectors.toSet())); |
| 98 | + } |
80 | 99 | } |
81 | 100 |
|
82 | | - var principalRoles = convertRoles(principal.getAttribute(rolesFieldName)); |
83 | | - if (principalRoles.isEmpty()) { |
84 | | - log.debug("Principal [{}] doesn't have any roles, nothing to do", principal.getName()); |
85 | | - return Collections.emptySet(); |
86 | | - } |
| 101 | + // Mapping groups from scopes |
| 102 | + Set<String> scopes = principal.getAuthorities().stream() |
| 103 | + .map(GrantedAuthority::getAuthority) |
| 104 | + .map(s -> s.replace("SCOPE_", "")) |
| 105 | + .collect(Collectors.toSet()); |
87 | 106 |
|
88 | | - log.debug("Token's groups: [{}]", String.join(",", principalRoles)); |
| 107 | + log.debug("Available scopes: [{}]. Mapping providers of type scope.", String.join(",", scopes)); |
89 | 108 |
|
90 | | - Set<String> roles = acs.getRoles() |
91 | | - .stream() |
| 109 | + roles.addAll(acs.getRoles().stream() |
92 | 110 | .filter(role -> role.getSubjects() |
93 | 111 | .stream() |
94 | 112 | .filter(s -> s.getProvider().equals(Provider.OAUTH)) |
95 | | - .filter(s -> s.getType().equals("role")) |
96 | | - .anyMatch(subject -> principalRoles.stream().anyMatch(subject::matches))) |
| 113 | + .filter(s -> s.getType().equals("scope")) |
| 114 | + .anyMatch(subject -> scopes.stream().anyMatch(subject::matches))) |
97 | 115 | .map(Role::getName) |
98 | | - .collect(Collectors.toSet()); |
| 116 | + .collect(Collectors.toSet())); |
99 | 117 |
|
100 | | - log.debug("Matched group roles: [{}]", String.join(", ", roles)); |
| 118 | + log.debug("Matched group/scope roles: [{}]", String.join(", ", roles)); |
101 | 119 |
|
102 | 120 | return roles; |
103 | 121 | } |
|
0 commit comments