reta commented on code in PR #3627:
URL: https://github.com/apache/cxf/pull/3627#discussion_r4372121073
##########
rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/filters/OAuthScopesFilter.java:
##########
@@ -113,27 +131,72 @@ protected void checkClient(Method m) {
}
}
protected void checkScopes(Method m) {
- List<String> methodScopes = scopesMap.get(m.getName());
- if (methodScopes == null) {
+ List<Scopes> annotationScopes = getAnnotationScopes(m);
+ List<String> configuredScopes = scopesMap.get(m.getName());
+ if (annotationScopes.isEmpty() && configuredScopes == null) {
return;
}
- boolean matchAll = scopesMatchAllMap.get(m.getName());
OAuthContext context = OAuthContextUtils.getContext(mc);
List<String> requestScopes = new LinkedList<>();
for (OAuthPermission perm : context.getPermissions()) {
- if (matchAll) {
- requestScopes.add(perm.getPermission());
- } else if (methodScopes.contains(perm.getPermission())) {
- return;
- }
+ requestScopes.add(perm.getPermission());
}
- if (!requestScopes.containsAll(methodScopes)) {
+ // Every rule which applies to the method has to be satisfied
+ boolean allowed = true;
+ for (Scopes scopes : annotationScopes) {
+ allowed &= isAllowed(requestScopes, Arrays.asList(scopes.value()),
scopes.matchAll());
+ }
+ if (configuredScopes != null) {
+ allowed &= isAllowed(requestScopes, configuredScopes,
+
Boolean.TRUE.equals(scopesMatchAllMap.get(m.getName())));
+ }
+ if (!allowed) {
LOG.warning("Scopes do not match");
throw ExceptionUtils.toForbiddenException(null, null);
}
+ }
+
+ private List<Scopes> getAnnotationScopes(Method m) {
+ String signature = getMethodSignature(m);
+ // A method-level annotation anywhere in the hierarchy takes
precedence over a
+ // class-level one, otherwise an inherited class-level @Scopes would
replace it
+ Scopes scopes = methodScopesBySignature.get(signature);
+ if (scopes == null) {
+ scopes = classScopesBySignature.get(signature);
+ }
+ if (scopes != null) {
+ return Collections.singletonList(scopes);
+ }
+ Set<Scopes> scopesForName = annotationScopesByName.get(m.getName());
+ return scopesForName == null ? Collections.emptyList() : new
ArrayList<>(scopesForName);
+ }
+
+ private static boolean isAllowed(List<String> requestScopes, List<String>
methodScopes,
+ boolean matchAll) {
+ if (matchAll || methodScopes.isEmpty()) {
+ return requestScopes.containsAll(methodScopes);
+ }
+ for (String scope : requestScopes) {
+ if (methodScopes.contains(scope)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ private static String getMethodSignature(Method m) {
Review Comment:
Do you think we could move it to util class (may be `ReflectionUtil`)?
(SimpleAuthorizingInterceptor::createMethodSig is doing exactly the same)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]