From 81bd7d07dad877b2619e69d337ccfc685463d134 Mon Sep 17 00:00:00 2001 From: zhouhao Date: Mon, 31 Jul 2023 18:52:37 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E5=BD=93oauth2=E6=8E=88=E6=9D=83*?= =?UTF-8?q?=E6=97=B6,=E4=BD=BF=E7=94=A8=E5=8D=95=E4=BE=8Btoken.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/authorization/Authentication.java | 9 +++++++++ .../simple/SimpleAuthentication.java | 1 + .../aop/AopAuthorizingControllerTest.java | 3 ++- .../web/oauth2/server/AccessTokenManager.java | 2 +- .../code/DefaultAuthorizationCodeGranter.java | 8 ++++++-- .../oauth2/server/impl/RedisAccessToken.java | 14 ++++++++++++-- .../server/impl/RedisAccessTokenManager.java | 18 ++++++++++-------- .../DefaultAuthorizationCodeGranterTest.java | 19 ++++++++++++------- 8 files changed, 53 insertions(+), 21 deletions(-) diff --git a/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/Authentication.java b/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/Authentication.java index 40ba06892..485170d77 100644 --- a/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/Authentication.java +++ b/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/Authentication.java @@ -201,6 +201,15 @@ public interface Authentication extends Serializable { */ Map getAttributes(); + /** + * 设置属性,注意: 此属性可能并不会被持久化,仅用于临时传递信息. + * @param key key + * @param value value + */ + default void setAttribute(String key,Serializable value){ + getAttributes().put(key,value); + } + /** * 合并权限 * diff --git a/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/simple/SimpleAuthentication.java b/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/simple/SimpleAuthentication.java index f4aac6b40..7d990be31 100644 --- a/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/simple/SimpleAuthentication.java +++ b/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/simple/SimpleAuthentication.java @@ -98,6 +98,7 @@ public class SimpleAuthentication implements Authentication { .collect(Collectors.toList()) ); authentication.setUser(user); + authentication.setAttributes(new HashMap<>(attributes)); return authentication; } diff --git a/hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/basic/aop/AopAuthorizingControllerTest.java b/hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/basic/aop/AopAuthorizingControllerTest.java index 31ed54700..f6f9c1949 100644 --- a/hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/basic/aop/AopAuthorizingControllerTest.java +++ b/hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/basic/aop/AopAuthorizingControllerTest.java @@ -1,5 +1,6 @@ package org.hswebframework.web.authorization.basic.aop; +import org.hswebframework.ezorm.core.CastUtil; import org.hswebframework.ezorm.core.param.Param; import org.hswebframework.ezorm.core.param.QueryParam; import org.hswebframework.ezorm.core.param.Term; @@ -134,7 +135,7 @@ public class AopAuthorizingControllerTest { .flatMapIterable(Function.identity()) .next() .map(Term::getValue) - .>map(Collection.class::cast) + .map(CastUtil::>cast) .flatMapIterable(Function.identity()) .next() .as(StepVerifier::create) diff --git a/hsweb-authorization/hsweb-authorization-oauth2/src/main/java/org/hswebframework/web/oauth2/server/AccessTokenManager.java b/hsweb-authorization/hsweb-authorization-oauth2/src/main/java/org/hswebframework/web/oauth2/server/AccessTokenManager.java index 7762b4e4c..d6669c6e2 100644 --- a/hsweb-authorization/hsweb-authorization-oauth2/src/main/java/org/hswebframework/web/oauth2/server/AccessTokenManager.java +++ b/hsweb-authorization/hsweb-authorization-oauth2/src/main/java/org/hswebframework/web/oauth2/server/AccessTokenManager.java @@ -25,7 +25,7 @@ public interface AccessTokenManager { * @param clientId clientId {@link OAuth2Client#getClientId()} * @param authentication 权限信息 * @param singleton 是否单例,如果为true,重复创建token将返回首次创建的token - * @return + * @return AccessToken */ Mono createAccessToken(String clientId, Authentication authentication, diff --git a/hsweb-authorization/hsweb-authorization-oauth2/src/main/java/org/hswebframework/web/oauth2/server/code/DefaultAuthorizationCodeGranter.java b/hsweb-authorization/hsweb-authorization-oauth2/src/main/java/org/hswebframework/web/oauth2/server/code/DefaultAuthorizationCodeGranter.java index 38e0341f6..d63b56883 100644 --- a/hsweb-authorization/hsweb-authorization-oauth2/src/main/java/org/hswebframework/web/oauth2/server/code/DefaultAuthorizationCodeGranter.java +++ b/hsweb-authorization/hsweb-authorization-oauth2/src/main/java/org/hswebframework/web/oauth2/server/code/DefaultAuthorizationCodeGranter.java @@ -58,9 +58,13 @@ public class DefaultAuthorizationCodeGranter implements AuthorizationCodeGranter ScopePredicate permissionPredicate = OAuth2ScopeUtils.createScopePredicate(codeCache.getScope()); - codeCache.setAuthentication(authentication.copy( + Authentication copy = authentication.copy( (permission, action) -> permissionPredicate.test(permission.getId(), action), - dimension -> permissionPredicate.test(dimension.getType().getId(), dimension.getId()))); + dimension -> permissionPredicate.test(dimension.getType().getId(), dimension.getId())); + + copy.setAttribute("scope", codeCache.getScope()); + + codeCache.setAuthentication(copy); return redis diff --git a/hsweb-authorization/hsweb-authorization-oauth2/src/main/java/org/hswebframework/web/oauth2/server/impl/RedisAccessToken.java b/hsweb-authorization/hsweb-authorization-oauth2/src/main/java/org/hswebframework/web/oauth2/server/impl/RedisAccessToken.java index 262116926..d5eaeaac8 100644 --- a/hsweb-authorization/hsweb-authorization-oauth2/src/main/java/org/hswebframework/web/oauth2/server/impl/RedisAccessToken.java +++ b/hsweb-authorization/hsweb-authorization-oauth2/src/main/java/org/hswebframework/web/oauth2/server/impl/RedisAccessToken.java @@ -27,8 +27,18 @@ public class RedisAccessToken implements Serializable { private boolean singleton; - public AccessToken toAccessToken(int expiresIn){ - AccessToken token=new AccessToken(); + public boolean storeAuth() { + boolean allowAllScope = authentication + .getAttribute("scope") + .map("*"::equals) + .orElse(false); + + //不是单例,并且没有授予全部权限 + return !singleton && !allowAllScope; + } + + public AccessToken toAccessToken(int expiresIn) { + AccessToken token = new AccessToken(); token.setAccessToken(accessToken); token.setRefreshToken(refreshToken); token.setExpiresIn(expiresIn); diff --git a/hsweb-authorization/hsweb-authorization-oauth2/src/main/java/org/hswebframework/web/oauth2/server/impl/RedisAccessTokenManager.java b/hsweb-authorization/hsweb-authorization-oauth2/src/main/java/org/hswebframework/web/oauth2/server/impl/RedisAccessTokenManager.java index 412cb00b8..29eb6dee5 100644 --- a/hsweb-authorization/hsweb-authorization-oauth2/src/main/java/org/hswebframework/web/oauth2/server/impl/RedisAccessTokenManager.java +++ b/hsweb-authorization/hsweb-authorization-oauth2/src/main/java/org/hswebframework/web/oauth2/server/impl/RedisAccessTokenManager.java @@ -96,14 +96,8 @@ public class RedisAccessTokenManager implements AccessTokenManager { } private Mono storeAuthToken(RedisAccessToken token) { - if (token.isSingleton()) { - return userTokenManager - .signIn(token.getAccessToken(), - createTokenType(token.getClientId()), - token.getAuthentication().getUser().getId(), - tokenExpireIn * 1000L) - .then(); - } else { + //保存独立的权限信息,通常是用户指定了特定的授权范围时生效. + if (token.storeAuth()) { return userTokenManager .signIn(token.getAccessToken(), createTokenType(token.getClientId()), @@ -111,6 +105,14 @@ public class RedisAccessTokenManager implements AccessTokenManager { tokenExpireIn * 1000L, token.getAuthentication()) .then(); + + } else { + return userTokenManager + .signIn(token.getAccessToken(), + createTokenType(token.getClientId()), + token.getAuthentication().getUser().getId(), + tokenExpireIn * 1000L) + .then(); } } diff --git a/hsweb-authorization/hsweb-authorization-oauth2/src/test/java/org/hswebframework/web/oauth2/server/code/DefaultAuthorizationCodeGranterTest.java b/hsweb-authorization/hsweb-authorization-oauth2/src/test/java/org/hswebframework/web/oauth2/server/code/DefaultAuthorizationCodeGranterTest.java index 6e0545441..2e93d1ef0 100644 --- a/hsweb-authorization/hsweb-authorization-oauth2/src/test/java/org/hswebframework/web/oauth2/server/code/DefaultAuthorizationCodeGranterTest.java +++ b/hsweb-authorization/hsweb-authorization-oauth2/src/test/java/org/hswebframework/web/oauth2/server/code/DefaultAuthorizationCodeGranterTest.java @@ -1,8 +1,7 @@ package org.hswebframework.web.oauth2.server.code; -import org.hswebframework.web.authorization.Permission; import org.hswebframework.web.authorization.simple.SimpleAuthentication; -import org.hswebframework.web.authorization.simple.SimplePermission; +import org.hswebframework.web.authorization.simple.SimpleUser; import org.hswebframework.web.oauth2.server.OAuth2Client; import org.hswebframework.web.oauth2.server.RedisHelper; import org.hswebframework.web.oauth2.server.impl.RedisAccessTokenManager; @@ -11,25 +10,31 @@ import org.springframework.context.support.StaticApplicationContext; import reactor.test.StepVerifier; import java.util.Collections; -import java.util.function.BiPredicate; - -import static org.junit.Assert.*; public class DefaultAuthorizationCodeGranterTest { @Test public void testRequestToken() { + StaticApplicationContext context = new StaticApplicationContext(); + context.refresh(); + context.start(); + DefaultAuthorizationCodeGranter codeGranter = new DefaultAuthorizationCodeGranter( - new RedisAccessTokenManager(RedisHelper.factory), new StaticApplicationContext(), RedisHelper.factory + new RedisAccessTokenManager(RedisHelper.factory), context, RedisHelper.factory ); OAuth2Client client = new OAuth2Client(); client.setClientId("test"); client.setClientSecret("test"); + SimpleAuthentication authentication = new SimpleAuthentication(); + authentication.setUser(SimpleUser + .builder() + .id("test") + .build()); codeGranter - .requestCode(new AuthorizationCodeRequest(client, new SimpleAuthentication(), Collections.emptyMap())) + .requestCode(new AuthorizationCodeRequest(client, authentication, Collections.emptyMap())) .doOnNext(System.out::println) .flatMap(response -> codeGranter .requestToken(new AuthorizationCodeTokenRequest(client, Collections.singletonMap("code", response.getCode()))))