From b95a83a242323faaf7b6af21fa81bc48fb171fb7 Mon Sep 17 00:00:00 2001 From: John Niang Date: Tue, 15 Oct 2024 16:51:22 +0800 Subject: [PATCH] Fix the problem of not being able to create PAT for OAuth2 user (#6870) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind bug /area core /milestone 2.20.x #### What this PR does / why we need it: This PR refactors check of whether the current user is a real user to fix the problem of not being able to create PAT for OAuth2 user. #### Does this PR introduce a user-facing change? ```release-note 修复通过 OAuth2 登录之后无法正常创建和恢复个人令牌的问题 ``` --- .../pat/impl/UserScopedPatHandlerImpl.java | 13 +++++++++---- .../app/security/authorization/AuthorityUtils.java | 13 ------------- .../security/authorization/AuthorityUtilsTest.java | 9 --------- 3 files changed, 9 insertions(+), 26 deletions(-) diff --git a/application/src/main/java/run/halo/app/security/authentication/pat/impl/UserScopedPatHandlerImpl.java b/application/src/main/java/run/halo/app/security/authentication/pat/impl/UserScopedPatHandlerImpl.java index 108479968..9a40919d4 100644 --- a/application/src/main/java/run/halo/app/security/authentication/pat/impl/UserScopedPatHandlerImpl.java +++ b/application/src/main/java/run/halo/app/security/authentication/pat/impl/UserScopedPatHandlerImpl.java @@ -11,6 +11,8 @@ import java.util.HashMap; import java.util.List; import java.util.Objects; import java.util.function.Predicate; +import org.springframework.security.authentication.AuthenticationTrustResolver; +import org.springframework.security.authentication.AuthenticationTrustResolverImpl; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.ReactiveSecurityContextHolder; @@ -64,6 +66,9 @@ public class UserScopedPatHandlerImpl implements UserScopedPatHandler { private Clock clock; + private final AuthenticationTrustResolver authTrustResolver = + new AuthenticationTrustResolverImpl(); + public UserScopedPatHandlerImpl(ReactiveExtensionClient client, CryptoService cryptoService, ExternalUrlSupplier externalUrl, @@ -84,8 +89,8 @@ public class UserScopedPatHandlerImpl implements UserScopedPatHandler { this.clock = clock; } - private static Mono mustBeRealUser(Mono authentication) { - return authentication.filter(AuthorityUtils::isRealUser) + private Mono mustBeAuthenticated(Mono authentication) { + return authentication.filter(authTrustResolver::isAuthenticated) // Non-username-password authentication could not access the API at any time. .switchIfEmpty(Mono.error(AccessDeniedException::new)); } @@ -94,7 +99,7 @@ public class UserScopedPatHandlerImpl implements UserScopedPatHandler { public Mono create(ServerRequest request) { return ReactiveSecurityContextHolder.getContext() .map(SecurityContext::getAuthentication) - .transform(UserScopedPatHandlerImpl::mustBeRealUser) + .transform(this::mustBeAuthenticated) .flatMap(auth -> request.bodyToMono(PersonalAccessToken.class) .switchIfEmpty( Mono.error(() -> new ServerWebInputException("Missing request body."))) @@ -222,7 +227,7 @@ public class UserScopedPatHandlerImpl implements UserScopedPatHandler { public Mono restore(ServerRequest request) { var restoredPat = ReactiveSecurityContextHolder.getContext() .map(SecurityContext::getAuthentication) - .transform(UserScopedPatHandlerImpl::mustBeRealUser) + .transform(this::mustBeAuthenticated) .flatMap(auth -> { var name = request.pathVariable("name"); return getPat(name, auth.getName()); diff --git a/application/src/main/java/run/halo/app/security/authorization/AuthorityUtils.java b/application/src/main/java/run/halo/app/security/authorization/AuthorityUtils.java index 75605e35f..846830aa0 100644 --- a/application/src/main/java/run/halo/app/security/authorization/AuthorityUtils.java +++ b/application/src/main/java/run/halo/app/security/authorization/AuthorityUtils.java @@ -4,9 +4,6 @@ import java.util.Collection; import java.util.Set; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; -import org.springframework.security.authentication.RememberMeAuthenticationToken; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; /** @@ -51,14 +48,4 @@ public enum AuthorityUtils { return roles.contains(SUPER_ROLE_NAME); } - /** - * Check if the authentication is a real user. - * - * @param authentication current authentication - * @return true if the authentication is a real user; false otherwise - */ - public static boolean isRealUser(Authentication authentication) { - return authentication instanceof UsernamePasswordAuthenticationToken - || authentication instanceof RememberMeAuthenticationToken; - } } diff --git a/application/src/test/java/run/halo/app/security/authorization/AuthorityUtilsTest.java b/application/src/test/java/run/halo/app/security/authorization/AuthorityUtilsTest.java index 4ac5082d3..1d9052a34 100644 --- a/application/src/test/java/run/halo/app/security/authorization/AuthorityUtilsTest.java +++ b/application/src/test/java/run/halo/app/security/authorization/AuthorityUtilsTest.java @@ -3,16 +3,12 @@ package run.halo.app.security.authorization; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.mock; import static run.halo.app.security.authorization.AuthorityUtils.authoritiesToRoles; import static run.halo.app.security.authorization.AuthorityUtils.containsSuperRole; -import static run.halo.app.security.authorization.AuthorityUtils.isRealUser; import java.util.List; import java.util.Set; import org.junit.jupiter.api.Test; -import org.springframework.security.authentication.RememberMeAuthenticationToken; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.authority.SimpleGrantedAuthority; class AuthorityUtilsTest { @@ -39,9 +35,4 @@ class AuthorityUtilsTest { assertFalse(containsSuperRole(Set.of("admin"))); } - @Test - void shouldReturnTrueWhenAuthenticationIsRealUser() { - assertTrue(isRealUser(mock(UsernamePasswordAuthenticationToken.class))); - assertTrue(isRealUser(mock(RememberMeAuthenticationToken.class))); - } } \ No newline at end of file