我们计划使用 JWT 来解析用户对微服务的权限。但我无法找到仅基于 Quarkus 权限的解决方案。在本文中,他们重点关注每个服务中存在的角色:https://quarkus.io/guides/security-jwt
有没有办法在Quarkus中基于JWT实现仅基于权限的授权?
背景:
我们拥有一个经过优化的解耦多租户自包含服务结构,我们可以轻松地将每个 SCS 作为自己的服务集成到另一个生态系统中。为此,我们设计了一个保留所有租户和角色的授权服务。每个 SCS 管理自己的权限,但不管理角色。他们注册到授权服务并向他公开所有权限。在授权服务内部,权限会按照角色进行分组,这样我们就可以更方便地为用户分配权限。
但是对于每个SCS中的授权,我们只想使用权限,这样SCS就不必知道/管理角色。该服务知道所提供的权限,并可以将其与所提供的 JWT 权限进行匹配。
我们想发送以下 JWT:
{
"UserData":{
"userId":#{USER_ID},
"email":"#{USER_EMAIL},
"tenants": {
"#{TENANTS_NAME}":{
"permissions": {
"#{PERMISSION_NAME}",
"#{PERMISSION_NAME}"
},
},
},
},
}
你可以这样做:
应用程序属性:
permissions.permission1=role1
permissions.permission2=role2
permissions.permission3=role3
import io.quarkus.security.identity.AuthenticationRequestContext;
import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.security.identity.SecurityIdentityAugmentor;
import io.quarkus.security.runtime.QuarkusSecurityIdentity;
import io.smallrye.mutiny.Uni;
import io.vertx.core.json.JsonObject;
import jakarta.enterprise.context.ApplicationScoped;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.eclipse.microprofile.jwt.JsonWebToken;
@ApplicationScoped
public class JwtRoleMapper implements SecurityIdentityAugmentor {
@ConfigProperty(name = "permissions")
Map<String, String> permissionMappings;
@Override
public Uni<SecurityIdentity> augment(SecurityIdentity identity, AuthenticationRequestContext authenticationRequestContext) {
var jwt = (JsonWebToken) identity.getPrincipal();
var tenants = (JsonObject) jwt.getClaim("tenants");
var builder = QuarkusSecurityIdentity.builder(identity);
tenants.getJsonObject("tenant_name").getJsonArray("permissions").forEach(permission ->
var role = this.permissionMappings.get(permission.toString());
if (role != null && !role.isBlank())
builder.addRole(role)
);
return Uni.createFrom().item(builder.build());
}
}
您明白了:检索原始 JWT,获取租户,迭代它并将其映射到配置中定义的某些角色。