Browse Source

优化scope判断

zhouhao 4 years ago
parent
commit
a8bd950310

+ 10 - 0
hsweb-authorization/hsweb-authorization-oauth2/src/main/java/org/hswebframework/web/oauth2/server/ScopePredicate.java

@@ -0,0 +1,10 @@
+package org.hswebframework.web.oauth2.server;
+
+import java.util.function.BiPredicate;
+
+@FunctionalInterface
+public interface ScopePredicate extends BiPredicate<String, String[]> {
+
+    boolean test(String permission, String... actions);
+
+}

+ 5 - 24
hsweb-authorization/hsweb-authorization-oauth2/src/main/java/org/hswebframework/web/oauth2/server/code/DefaultAuthorizationCodeGranter.java

@@ -2,24 +2,22 @@ package org.hswebframework.web.oauth2.server.code;
 
 import lombok.AllArgsConstructor;
 import org.hswebframework.web.authorization.Authentication;
-import org.hswebframework.web.authorization.Permission;
 import org.hswebframework.web.id.IDGenerator;
 import org.hswebframework.web.oauth2.ErrorType;
 import org.hswebframework.web.oauth2.OAuth2Exception;
 import org.hswebframework.web.oauth2.server.AccessToken;
 import org.hswebframework.web.oauth2.server.AccessTokenManager;
 import org.hswebframework.web.oauth2.server.OAuth2Client;
+import org.hswebframework.web.oauth2.server.ScopePredicate;
+import org.hswebframework.web.oauth2.server.utils.OAuth2ScopeUtils;
 import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory;
 import org.springframework.data.redis.core.ReactiveRedisOperations;
 import org.springframework.data.redis.core.ReactiveRedisTemplate;
 import org.springframework.data.redis.serializer.RedisSerializationContext;
 import org.springframework.data.redis.serializer.RedisSerializer;
-import org.springframework.util.StringUtils;
 import reactor.core.publisher.Mono;
 
 import java.time.Duration;
-import java.util.*;
-import java.util.function.BiPredicate;
 
 @AllArgsConstructor
 public class DefaultAuthorizationCodeGranter implements AuthorizationCodeGranter {
@@ -49,9 +47,10 @@ public class DefaultAuthorizationCodeGranter implements AuthorizationCodeGranter
         request.getParameter("scope").map(String::valueOf).ifPresent(codeCache::setScope);
         codeCache.setCode(code);
         codeCache.setClientId(client.getClientId());
-        codeCache.setAuthentication(authentication.copy(createPredicate(codeCache.getScope()), dimension -> true));
+        ScopePredicate permissionPredicate = OAuth2ScopeUtils.createScopePredicate(codeCache.getScope());
+
+        codeCache.setAuthentication(authentication.copy((permission, action) -> permissionPredicate.test(permission.getId(), action), dimension -> true));
 
-        createPredicate(codeCache.getScope());
 
         return redis
                 .opsForValue()
@@ -59,24 +58,6 @@ public class DefaultAuthorizationCodeGranter implements AuthorizationCodeGranter
                 .thenReturn(new AuthorizationCodeResponse(code));
     }
 
-    static BiPredicate<Permission, String> createPredicate(String scopeStr) {
-        if (StringUtils.isEmpty(scopeStr)) {
-            return ((permission, s) -> false);
-        }
-        String[] scopes = scopeStr.split("[ ,\n]");
-        Map<String, Set<String>> actions = new HashMap<>();
-        for (String scope : scopes) {
-            String[] permissions = scope.split("[:]");
-            String per = permissions[0];
-            Set<String> acts = actions.computeIfAbsent(per, k -> new HashSet<>());
-            acts.addAll(Arrays.asList(permissions).subList(1, permissions.length));
-        }
-
-        return ((permission, action) -> Optional
-                .ofNullable(actions.get(permission.getId()))
-                .map(acts -> acts.contains(action))
-                .orElse(false));
-    }
 
     private String getRedisKey(String code) {
         return "oauth2-code:" + code;

+ 32 - 0
hsweb-authorization/hsweb-authorization-oauth2/src/main/java/org/hswebframework/web/oauth2/server/utils/OAuth2ScopeUtils.java

@@ -0,0 +1,32 @@
+package org.hswebframework.web.oauth2.server.utils;
+
+import org.hswebframework.web.oauth2.server.ScopePredicate;
+import org.springframework.util.StringUtils;
+
+import java.util.*;
+
+/**
+ * @author zhouhao
+ * @since 4.0.8
+ */
+public class OAuth2ScopeUtils {
+
+    public static ScopePredicate createScopePredicate(String scopeStr) {
+        if (StringUtils.isEmpty(scopeStr)) {
+            return ((permission, action) -> false);
+        }
+        String[] scopes = scopeStr.split("[ ,\n]");
+        Map<String, Set<String>> actions = new HashMap<>();
+        for (String scope : scopes) {
+            String[] permissions = scope.split("[:]");
+            String per = permissions[0];
+            Set<String> acts = actions.computeIfAbsent(per, k -> new HashSet<>());
+            acts.addAll(Arrays.asList(permissions).subList(1, permissions.length));
+        }
+
+        return ((permission, action) -> Optional
+                .ofNullable(actions.get(permission))
+                .map(acts -> action.length == 0 || acts.containsAll(Arrays.asList(action)))
+                .orElse(false));
+    }
+}

+ 0 - 27
hsweb-authorization/hsweb-authorization-oauth2/src/test/java/org/hswebframework/web/oauth2/server/code/DefaultAuthorizationCodeGranterTest.java

@@ -16,33 +16,6 @@ import static org.junit.Assert.*;
 
 public class DefaultAuthorizationCodeGranterTest {
 
-
-    @Test
-    public void testPermission() {
-        BiPredicate<Permission, String> predicate = DefaultAuthorizationCodeGranter.createPredicate("user:info device:query");
-
-        {
-            SimplePermission permission=new SimplePermission();
-            permission.setId("user");
-            permission.setActions(Collections.singleton("info"));
-
-
-            assertTrue(predicate.test(permission,"info"));
-            assertFalse(predicate.test(permission,"info2"));
-        }
-
-        {
-            SimplePermission permission=new SimplePermission();
-            permission.setId("device");
-            permission.setActions(Collections.singleton("query"));
-
-
-            assertTrue(predicate.test(permission,"query"));
-            assertFalse(predicate.test(permission,"query2"));
-        }
-
-    }
-
     @Test
     public void testRequestToken() {
 

+ 35 - 0
hsweb-authorization/hsweb-authorization-oauth2/src/test/java/org/hswebframework/web/oauth2/server/utils/OAuth2ScopeUtilsTest.java

@@ -0,0 +1,35 @@
+package org.hswebframework.web.oauth2.server.utils;
+
+import org.hswebframework.web.oauth2.server.ScopePredicate;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class OAuth2ScopeUtilsTest {
+
+
+    @Test
+    public void testEmpty() {
+        ScopePredicate predicate = OAuth2ScopeUtils.createScopePredicate(null);
+        assertFalse(predicate.test("basic"));
+    }
+
+    @Test
+    public void testScope() {
+        ScopePredicate predicate = OAuth2ScopeUtils.createScopePredicate("basic user:info device:query");
+
+        assertTrue(predicate.test("basic"));
+        {
+
+            assertTrue(predicate.test("user", "info"));
+            assertFalse(predicate.test("user", "info2"));
+        }
+
+        {
+            assertTrue(predicate.test("device", "query"));
+            assertFalse(predicate.test("device", "query2"));
+        }
+
+    }
+}