|
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