Fix the problem the PAT could not be created or restored while logging in with remember-me (#6007)

#### What type of PR is this?

/kind bug
/area core
/milestone 2.16.0

#### What this PR does / why we need it:

PAT could not be created or restored while logging in with remember-me due to lack of RememberMeAuthenticationToken check.

#### Which issue(s) this PR fixes:

Fixes https://github.com/halo-dev/halo/issues/6000

#### Special notes for your reviewer:

1. Log in with remember-me
2. Create a PAT or restore a PAT
3. See the result

#### Does this PR introduce a user-facing change?

```release-note
None
```
pull/6011/head
John Niang 2024-05-29 11:13:10 +08:00 committed by GitHub
parent dad6610cce
commit 608f2bbca3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 25 additions and 2 deletions

View File

@ -11,7 +11,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
@ -86,7 +85,7 @@ public class UserScopedPatHandlerImpl implements UserScopedPatHandler {
}
private static Mono<Authentication> mustBeRealUser(Mono<Authentication> authentication) {
return authentication.filter(UsernamePasswordAuthenticationToken.class::isInstance)
return authentication.filter(AuthorityUtils::isRealUser)
// Non-username-password authentication could not access the API at any time.
.switchIfEmpty(Mono.error(AccessDeniedException::new));
}

View File

@ -4,6 +4,9 @@ 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;
/**
@ -44,4 +47,15 @@ public enum AuthorityUtils {
public static boolean containsSuperRole(Collection<String> roles) {
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;
}
}

View File

@ -3,12 +3,16 @@ 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 {
@ -34,4 +38,10 @@ class AuthorityUtilsTest {
assertTrue(containsSuperRole(Set.of("super-role", "admin")));
assertFalse(containsSuperRole(Set.of("admin")));
}
@Test
void shouldReturnTrueWhenAuthenticationIsRealUser() {
assertTrue(isRealUser(mock(UsernamePasswordAuthenticationToken.class)));
assertTrue(isRealUser(mock(RememberMeAuthenticationToken.class)));
}
}