Files
baiyue-firstleg/common-security/src/test/java/com/baiyue/common/security/JwtClaimsMapperTest.java
T

93 lines
3.9 KiB
Java

package com.baiyue.common.security;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.security.oauth2.jwt.Jwt;
import java.time.Instant;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@DisplayName("JWT 声明映射功能")
class JwtClaimsMapperTest {
@Test
void mapsTenantUserRolesAndPermissions() {
Jwt jwt = Jwt.withTokenValue("token")
.header("alg", "none")
.subject("subject")
.issuedAt(Instant.now())
.expiresAt(Instant.now().plusSeconds(60))
.claim("user_id", 42L)
.claim("tenant_id", "7")
.claim("username", "alice")
.claim("app_code", "MERCHANT")
.claim("client_type", "MERCHANT")
.claim("permissions", List.of("order:read", "order:create"))
.claim("roles", List.of("ADMIN"))
.build();
AccessTokenSession session = new AccessTokenSession(1, 42L,
java.util.Set.of("ADMIN"), java.util.Set.of("order:read", "order:create"));
BaiyueJwtAuthenticationToken authentication = new JwtClaimsMapper().map(jwt, session);
assertThat(authentication.getPrincipal().userId()).isEqualTo(42L);
assertThat(authentication.getPrincipal().tenantId()).isEqualTo(7L);
assertThat(authentication.getAuthorities()).extracting("authority")
.contains("order:read", "order:create", "ROLE_ADMIN", "APP_MERCHANT");
}
@Test
void ignoresAuthorizationClaimsInJwt() {
Jwt jwt = Jwt.withTokenValue("token").header("alg", "none").subject("42")
.issuedAt(Instant.now()).expiresAt(Instant.now().plusSeconds(60))
.claim("user_id", 42L).claim("tenant_id", 0L).claim("app_code", "PLATFORM")
.claim("permissions", List.of("platform:forged"))
.claim("roles", List.of("FORGED")).build();
BaiyueJwtAuthenticationToken authentication = new JwtClaimsMapper().map(jwt,
new AccessTokenSession(1, 42L, java.util.Set.of(), java.util.Set.of("platform:real")));
assertThat(authentication.getAuthorities()).extracting("authority")
.contains("platform:real", "APP_PLATFORM")
.doesNotContain("platform:forged", "ROLE_FORGED");
}
@Test
void fallsBackToNumericSubjectForUserId() {
Jwt jwt = Jwt.withTokenValue("token")
.header("alg", "none")
.subject("99")
.issuedAt(Instant.now())
.expiresAt(Instant.now().plusSeconds(60))
.claim("tenant_id", 0L)
.claim("app_code", "PLATFORM")
.build();
BaiyueJwtAuthenticationToken authentication = new JwtClaimsMapper().map(jwt);
assertThat(authentication.getPrincipal().userId()).isEqualTo(99L);
assertThat(authentication.getAuthorities()).extracting("authority").contains("APP_PLATFORM");
}
@Test
void mapsImpersonationAndForcedPasswordClaims() {
Jwt jwt = Jwt.withTokenValue("token")
.header("alg", "none")
.subject("99")
.issuedAt(Instant.now())
.expiresAt(Instant.now().plusSeconds(60))
.claim("tenant_id", 7L)
.claim("app_code", "MERCHANT")
.claim("impersonated", true)
.claim("actor_user_id", 42L)
.claim("actor_membership_id", 43L)
.claim("password_change_required", true)
.build();
AuthenticatedUser user = new JwtClaimsMapper().map(jwt).getPrincipal();
assertThat(user.impersonated()).isTrue();
assertThat(user.actorUserId()).isEqualTo(42L);
assertThat(user.actorMembershipId()).isEqualTo(43L);
assertThat(user.passwordChangeRequired()).isTrue();
}
}