Request Body removed after Keycloak's Policy Enforcer Evaluation

360 views Asked by At

I am trying to get familiar with the Authorization Services concepts from Keycloak by playing around with the app-authz-rest-springboot from Keycloak-Quickstarts.

I run a keycloak-server and the app-authz-rest-springboot locally, following the guidelines and they work as expected. However, I face an issue when I try to add a new endpoint to the app and secure it as the other endpoints that are provided in the app-authz-rest-springboot.

What I try to do is to forward the request body of an HTTP request to the policy-enforcer of keycloak's client and decide if the request should be granted based on the request body.

On the application side I have the following:

  1. The new endpoint:
  @PostMapping("/api/example")
  public String exampleEndpoint(@RequestBody RequestDto requestDto) {
    System.out.println(requestDto.getUserId());
    return createResponse();
  }
  1. The request body for the endpoint:
public class RequestDto {

  public String userId;

  public RequestDto() {}

  public RequestDto(String userId) {
    this.userId = userId;
  }

  public String getUserId() {
    return userId;
  }

  public void setUserId(String userId) {
    this.userId = userId;
  }

  @Override
  public String toString() {
    return "RequestDto{" + "userId=" + userId + '}';
  }
}
  1. The policy-enforcer-config to push the request body to the keycloak-policy-enforcer for the permission evaluation of the endpoint
keycloak.policy-enforcer-config.paths[3].path=/api/example
keycloak.policy-enforcer-config.paths[3].claimInformationPointConfig.claims[user.id]={request.body['/userId']}

On the keycloak-server side:

  1. A Resource called Example Resource binding /api/example (the aforementioned endpoint)
  2. A custom js policy, which prints the request-body of the endpoint to stdout and always grants the request.
var context = $evaluation.context;
var attributes = context.attributes;
print(attributes.getValue('user.id').asString(0));
$evaluation.grant();
  1. A Permission that binds the Example Resource(1) with the custom js policy(2)

I make a request to the application using Postman with a request-body:

{
    "userId": "blablabla"
}

The custom js policy script prints the request body 10:37:46,387 INFO [stdout] (default task-6) blablabla Which means that the application pushes correctly the request body to the policy-enforcer. Additionally, keycloak grants the request successfully.

Although, on the application side, after the keycloak's policy enforcer interception, the request fails with a 400 Bad Request HTTP status and a response:

{
    "timestamp": "2021-11-25T08:37:46.454+0000",
    "status": 400,
    "error": "Bad Request",
    "message": "Required request body is missing: public java.lang.String org.keycloak.quickstart.springboot.web.ApplicationController.exampleEndpoint(org.keycloak.quickstart.springboot.web.RequestDto)",
    "path": "/api/example"
}

It seems like the policy enforcer from keycloak somehow "removed" the request body from the request after the permission evaluation. It is weird because as I mentioned, the claims have been successfully pushed to the keycloak and the request has been successfully granted.

Does anyone have faced a similar issue? Or is there any post or example online which I can follow? I googled it a lot but unfortunately, I haven't found anything yet. And, the keycloak-quickstarts do not provide any similar example pushing the request body to the policy-enforcer. The examples are limited in showing how to forward request parameters to keycloak.

0

There are 0 answers