Quarkus 1.13注入AuthzClient异常解决方案及用户权限校验咨询
Quarkus 1.13 AuthzClient注入报错解决方案及替代权限校验方案
注入失败原因及修复方案
你遇到的UnsatisfiedResolutionException是因为Quarkus 1.13默认不会自动注册AuthzClient的CDI Bean,需要先完成前置配置:
- 确认已引入依赖
io.quarkus:quarkus-keycloak-authorization,仅引入基础Keycloak扩展不会包含AuthzClient相关能力 - 在
application.properties中配置完整Keycloak参数:quarkus.keycloak.auth-server-url、quarkus.keycloak.realm、quarkus.keycloak.client-id、quarkus.keycloak.credentials.secret,同时开启quarkus.keycloak.policy-enforcer.enable=true,开启策略执行器后Quarkus会自动注册AuthzClient Bean - 若不需要开启全局策略执行器,可手动添加Producer创建AuthzClient:
import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Produces; import org.keycloak.authorization.client.AuthzClient; @ApplicationScoped public class AuthzClientProducer { @Produces public AuthzClient produceAuthzClient() { // 会自动读取classpath下的keycloak.json配置,也可传入自定义配置对象 return AuthzClient.create(); } }
无需AuthzClient的access token权限校验方案
如果不想处理AuthzClient的注入问题,可使用以下两种方案直接校验权限:
方案1:使用Quarkus自带的安全上下文校验
如果项目已经接入Quarkus Keycloak扩展,请求携带的access token会被自动解析为安全上下文对象,直接注入即可校验:
import io.quarkus.security.identity.SecurityIdentity; import org.eclipse.microprofile.jwt.JsonWebToken; import javax.inject.Inject; public class PermissionService { @Inject SecurityIdentity securityIdentity; @Inject JsonWebToken jwt; // 校验内置角色 public boolean hasRole(String roleName) { return securityIdentity.hasRole(roleName); } // 校验自定义claim中的权限 public boolean hasCustomPermission(String requiredPermission) { // 假设权限存在名为permissions的数组claim中,可根据实际claim名称调整 return jwt.getClaim("permissions") != null && jwt.getClaimAsStringList("permissions").contains(requiredPermission); } }
方案2:调用Keycloak远程授权接口实时校验
如果需要和Keycloak服务端实时核对权限,可手动发起HTTP请求校验:
import javax.ws.rs.core.Form; import javax.ws.rs.core.Response; import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; public class RemotePermissionChecker { public boolean checkPermission(String accessToken, String keycloakBaseUrl, String realm, String clientId, String requiredPermission) { Form form = new Form(); form.param("grant_type", "urn:ietf:params:oauth:grant-type:uma-ticket"); form.param("audience", clientId); form.param("permission", requiredPermission); Response response = ResteasyClientBuilder.newClient() .target(keycloakBaseUrl + "/realms/" + realm + "/protocol/openid-connect/token") .request() .header("Authorization", "Bearer " + accessToken) .post(javax.ws.rs.client.Entity.form(form)); // 状态码200代表持有权限,403代表无权限 return response.getStatus() == 200; } }
内容的提问来源于stack exchange,提问作者jithset
相关产品推荐
相关产品推荐

