暂存提交
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
package com.baiyue.common.security;
|
||||
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* JWT 声明映射器,将令牌中的用户、租户、端类型和权限声明转换为认证主体与授权集合。
|
||||
*/
|
||||
public class JwtClaimsMapper {
|
||||
public BaiyueJwtAuthenticationToken map(Jwt jwt) {
|
||||
Set<String> permissions = new LinkedHashSet<>();
|
||||
addClaimValues(permissions, jwt.getClaims().get("authorities"));
|
||||
addClaimValues(permissions, jwt.getClaims().get("permissions"));
|
||||
addClaimValues(permissions, jwt.getClaims().get("scope"));
|
||||
addRoles(permissions, jwt.getClaims().get("roles"));
|
||||
|
||||
String appCode = jwt.getClaimAsString("app_code");
|
||||
if (appCode != null && !appCode.isBlank()) {
|
||||
permissions.add("APP_" + appCode.toUpperCase(java.util.Locale.ROOT));
|
||||
}
|
||||
String username = firstNonBlank(jwt.getClaimAsString("username"),
|
||||
jwt.getClaimAsString("preferred_username"), jwt.getSubject());
|
||||
Long userId = longClaim(jwt, "user_id");
|
||||
AuthenticatedUser user = new AuthenticatedUser(
|
||||
userId == null ? longValue(jwt.getSubject()) : userId,
|
||||
longClaim(jwt, "tenant_id"),
|
||||
longClaim(jwt, "operator_tenant_id"),
|
||||
longClaim(jwt, "membership_id"),
|
||||
username,
|
||||
jwt.getClaimAsString("app_code"),
|
||||
jwt.getClaimAsString("client_type"),
|
||||
permissions);
|
||||
List<SimpleGrantedAuthority> authorities = permissions.stream()
|
||||
.map(SimpleGrantedAuthority::new).toList();
|
||||
return new BaiyueJwtAuthenticationToken(user, jwt.getTokenValue(), authorities);
|
||||
}
|
||||
|
||||
private void addClaimValues(Set<String> target, Object value) {
|
||||
if (value instanceof Collection<?> collection) {
|
||||
collection.stream().map(Object::toString).filter(s -> !s.isBlank()).forEach(target::add);
|
||||
} else if (value instanceof String text) {
|
||||
for (String item : text.split("[ ,]+")) {
|
||||
if (!item.isBlank()) target.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addRoles(Set<String> target, Object value) {
|
||||
Set<String> roles = new LinkedHashSet<>();
|
||||
addClaimValues(roles, value);
|
||||
roles.stream().map(role -> role.startsWith("ROLE_") ? role : "ROLE_" + role).forEach(target::add);
|
||||
}
|
||||
|
||||
private Long longValue(String value) {
|
||||
if (value == null || value.isBlank()) return null;
|
||||
try { return Long.valueOf(value); }
|
||||
catch (NumberFormatException ignored) { return null; }
|
||||
}
|
||||
|
||||
private Long longClaim(Jwt jwt, String name) {
|
||||
Object value = jwt.getClaims().get(name);
|
||||
if (value instanceof Number number) return number.longValue();
|
||||
if (value instanceof String text) return longValue(text);
|
||||
return null;
|
||||
}
|
||||
|
||||
private String firstNonBlank(String... values) {
|
||||
for (String value : values) if (value != null && !value.isBlank()) return value;
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user