1.16. 以编程方式检查权限范围
除了资源权限外,您还可以定义方法范围。范围通常代表对资源执行的操作。您可以使用方法范围创建强制 Keycloak 授权策略。例如:
# path policy with enforced scope 'read' for method 'GET'
quarkus.keycloak.policy-enforcer.paths.1.name=Scope Permission Resource
quarkus.keycloak.policy-enforcer.paths.1.paths=/api/protected/standard-way
quarkus.keycloak.policy-enforcer.paths.1.methods.get.method=GET
quarkus.keycloak.policy-enforcer.paths.1.methods.get.scopes=read
# path policies without scope
quarkus.keycloak.policy-enforcer.paths.2.name=Scope Permission Resource
quarkus.keycloak.policy-enforcer.paths.2.paths=/api/protected/programmatic-way,/api/protected/annotation-way
- 1
- 用户必须具有资源权限
范围资源和范围读取
Keycloak 策略 Enforcer 保护 /api/protected/standard-way 请求路径,不再需要注解,如 @RolesAllowed。然而,在某些情况下,您可能需要执行编程检查。
您可以通过将 SecurityIdentity 实例注入 Bean 来达到此目的,如下例所示。或者,您可以通过使用 @PermissionsAllowed 注解资源方法来获得相同的结果。以下示例演示了三种资源方法,每个资源都需要相同的 读取 范围:
import java.security.BasicPermission;
import java.util.List;
import jakarta.inject.Inject;
import jakarta.ws.rs.ForbiddenException;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import org.keycloak.representations.idm.authorization.Permission;
import io.quarkus.security.PermissionsAllowed;
import io.quarkus.security.identity.SecurityIdentity;
import io.smallrye.mutiny.Uni;
@Path("/api/protected")
public class ProtectedResource {
@Inject
SecurityIdentity identity;
@GET
@Path("/standard-way")
public Uni<List<Permission>> standardWay() {
return Uni.createFrom().item(identity.<List<Permission>> getAttribute("permissions"));
}
@GET
@Path("/programmatic-way")
public Uni<List<Permission>> programmaticWay() {
var requiredPermission = new BasicPermission("Scope Permission Resource") {
@Override
public String getActions() {
return "read";
}
};
return identity.checkPermission(requiredPermission).onItem()
.transform(granted -> {
if (granted) {
return identity.getAttribute("permissions");
}
throw new ForbiddenException();
});
}
@PermissionsAllowed("Scope Permission Resource:read")
@GET
@Path("/annotation-way")
public Uni<List<Permission>> annotationWay() {
return Uni.createFrom().item(identity.<List<Permission>> getAttribute("permissions"));
}
}
- 1
/standard-way子路径需要资源权限和读取范围,具体取决于application.properties文件中设置的配置。- 2
- 默认情况下,
/programmatic-way子路径只检查Scope Permission Resource权限。但是,您可以使用SecurityIdentity#checkPermission来强制实施额外的约束,如范围要求。 - 3
/annotation-way的@PermissionsAllowed注释限制对具有Scope Permission Resource权限以及读取范围的请求的访问。如需更多信息,请参阅 安全 授权指南中的使用注解 授权部分。