refactor: 当oauth2授权*时,使用单例token.

This commit is contained in:
zhouhao
2023-07-31 18:52:37 +08:00
parent 181607e507
commit 81bd7d07da
8 changed files with 53 additions and 21 deletions

View File

@@ -201,6 +201,15 @@ public interface Authentication extends Serializable {
*/
Map<String, Serializable> getAttributes();
/**
* 设置属性,注意: 此属性可能并不会被持久化,仅用于临时传递信息.
* @param key key
* @param value value
*/
default void setAttribute(String key,Serializable value){
getAttributes().put(key,value);
}
/**
* 合并权限
*

View File

@@ -98,6 +98,7 @@ public class SimpleAuthentication implements Authentication {
.collect(Collectors.toList())
);
authentication.setUser(user);
authentication.setAttributes(new HashMap<>(attributes));
return authentication;
}

View File

@@ -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)
.<Collection<Object>>map(Collection.class::cast)
.map(CastUtil::<Collection<Object>>cast)
.flatMapIterable(Function.identity())
.next()
.as(StepVerifier::create)

View File

@@ -25,7 +25,7 @@ public interface AccessTokenManager {
* @param clientId clientId {@link OAuth2Client#getClientId()}
* @param authentication 权限信息
* @param singleton 是否单例,如果为true,重复创建token将返回首次创建的token
* @return
* @return AccessToken
*/
Mono<AccessToken> createAccessToken(String clientId,
Authentication authentication,

View File

@@ -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

View File

@@ -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);

View File

@@ -96,14 +96,8 @@ public class RedisAccessTokenManager implements AccessTokenManager {
}
private Mono<Void> 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();
}
}

View File

@@ -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()))))