Keycloak+Quarkus环境下无需@RolesRequired如何获取用户名?
解决Quarkus无需@RolesRequired获取Keycloak用户名的问题
核心原因
Quarkus默认对未添加安全注解的端点做了性能优化,不会主动解析认证令牌并初始化身份上下文,导致identity对象无法获取用户信息。只有当@RolesRequired这类安全注解触发时,框架才会完成身份验证流程,填充用户数据。
解决方案
1. 使用@Authenticated注解
这个注解仅要求请求已完成认证,不需要指定具体角色,能触发身份上下文初始化,同时保留接口的无角色限制:
@GET @Path('me') @Authenticated public User me() { return new User(identity); }
2. 配置全局默认认证规则
在application.properties中设置全局路径默认需要认证,再对不需要认证的接口用@PermitAll放行:
# 全局路径默认要求认证 quarkus.http.auth.permission.authenticated.paths=/* quarkus.http.auth.permission.authenticated.policy=authenticated
无需认证的接口示例:
@GET @Path('public') @PermitAll public String publicEndpoint() { return "公开内容"; }
3. 手动解析令牌(不推荐)
如果不想依赖安全注解,可以直接从请求头提取Bearer令牌并解析:
import io.smallrye.jwt.build.Jwt; import jakarta.ws.rs.HeaderParam; import jakarta.ws.rs.core.HttpHeaders; import jakarta.ws.rs.NotAuthorizedException; @GET @Path('me') public User me(@HeaderParam(HttpHeaders.AUTHORIZATION) String authHeader) { if (authHeader == null || !authHeader.startsWith("Bearer ")) { throw new NotAuthorizedException("无效或缺失认证令牌"); } String token = authHeader.substring(7); // 解析JWT令牌获取用户名 String username = Jwt.decode(token).getClaim("preferred_username").toString(); return new User(username); }
这种方法需要手动处理令牌验证,不如框架自带的安全上下文可靠,仅适合特殊场景。
内容的提问来源于stack exchange,提问作者madswed
相关产品推荐
相关产品推荐

