You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quarkus OIDC:从userInfo而非idToken提取角色的实现方法

解决Quarkus从OIDC UserInfo提取角色用于@RolesAllowed的问题

方法1:通过配置直接实现(最简单)

Quarkus OIDC提供了现成的配置项,可直接指定从UserInfo中提取角色,无需编写自定义代码。在application.properties中添加以下配置:

# 指定角色来源为UserInfo
quarkus.oidc.roles.source=user-info
# 指定UserInfo中存储角色的声明字段名
quarkus.oidc.roles.claim-path=groups

配置完成后,Quarkus会自动从UserInfo的groups字段中提取角色,供@RolesAllowed注解使用。

方法2:自定义角色提取器(适用于复杂逻辑场景)

如果需要对角色做额外的转换或过滤逻辑,可以实现OidcRolesExtractor接口,手动从UserInfo中提取角色:

import io.quarkus.oidc.OidcIdentityProvider;
import io.quarkus.oidc.runtime.OidcRolesExtractor;
import io.quarkus.security.identity.SecurityIdentity;
import jakarta.enterprise.context.ApplicationScoped;
import org.eclipse.microprofile.jwt.JsonWebToken;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

@ApplicationScoped
public class CustomUserInfoRolesExtractor implements OidcRolesExtractor {

    @Override
    public Set<String> extractRoles(OidcIdentityProvider provider, JsonWebToken jwt, SecurityIdentity identity) {
        // SecurityIdentity的attributes中包含UserInfo的所有声明
        Object groupsAttr = identity.getAttributes().get("groups");
        Set<String> roles = new HashSet<>();

        if (groupsAttr instanceof Set) {
            roles.addAll((Set<String>) groupsAttr);
        } else if (groupsAttr instanceof Iterable) {
            ((Iterable<?>) groupsAttr).forEach(item -> roles.add(item.toString()));
        } else if (groupsAttr != null) {
            roles.add(groupsAttr.toString());
        }

        return roles;
    }
}

然后在配置中指定使用这个自定义提取器:

quarkus.oidc.roles.extractor=com.yourpackage.CustomUserInfoRolesExtractor

关于Augmentor的补充说明

你提到的Augmentor其实也可以实现需求,SecurityIdentityAugmentor的augment方法参数中的SecurityIdentity已经包含了UserInfo的属性,可从中提取角色并添加到身份信息中:

import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.security.identity.SecurityIdentityAugmentor;
import jakarta.enterprise.context.ApplicationScoped;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;

@ApplicationScoped
public class RolesAugmentor implements SecurityIdentityAugmentor {

    @Override
    public CompletionStage<SecurityIdentity> augment(SecurityIdentity identity, AugmentorContext context) {
        Object groupsAttr = identity.getAttributes().get("groups");
        Set<String> roles = new HashSet<>();

        // 转换groups属性为角色集合,逻辑同自定义提取器
        if (groupsAttr instanceof Set) {
            roles.addAll((Set<String>) groupsAttr);
        } else if (groupsAttr instanceof Iterable) {
            ((Iterable<?>) groupsAttr).forEach(item -> roles.add(item.toString()));
        } else if (groupsAttr != null) {
            roles.add(groupsAttr.toString());
        }

        // 返回添加了角色的新SecurityIdentity
        return CompletableFuture.completedFuture(identity.withRoles(roles));
    }
}

不过这种方式不如前两种直接,因为Quarkus OIDC已经提供了专门的角色提取机制,优先推荐配置或自定义提取器方案。

内容的提问来源于stack exchange,提问作者badnun872

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 05:52:46