sarah w
sarah w

Reputation: 3515

keycloak unknown error while creating a new resource via rest api

I am trying to create a new resource in keycloak on keycloak UI I looged in with admin account then I created a realm called demo and a user abc in it and created a client clientA after that I have created a new resource named resourceA with scopes and policy and permissions while on keycloak ui everything is working fine resource was created the user abc has realm roles as admin, uma_authorization and client role of the client clienA is uma_protection

when i try to create a resource via rest api i am getting {"error":"unknown_error"}

Here are the steps I am following obtained a pat as shown here

curl -X POST \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -d 'grant_type=client_credentials&client_id=clientA&client_secret=given client secret' \
    "http://localhost:8080/auth/realms/demo/protocol/openid-connect/token"

I got the access token (pat) then I followed next step

    curl -v -X POST \
      http://localhost:8080/auth/realms/demo/authz/protection/resource_set \
      -H 'Authorization: Bearer '$here i am adding the pat i received from the previous step \
      -H 'Content-Type: application/json' \
      -d '{
      "resource_scopes":[  
        "read-public",
        "post-updates",
        "read-private",
        "http://www.example.com/scopes/all"
      ],
      "icon_uri":"http://www.example.com/icons/sharesocial.png",
      "name":"Tweedl Social Service",
      "type":"http://www.example.com/rsrcs/socialstream/140-compatible"     
      }'

I got {"error":"unknown_error"} as a response with status code 400 Bad request. What am I missing here ?

Upvotes: 0

Views: 2894

Answers (1)

xardbaiz
xardbaiz

Reputation: 815

I know what it feels like :)

Reason

org.keycloak.services.error.KeycloakErrorHandler gets error text from WebApplicationException::getMessage method result.

public Response toResponse(Throwable throwable) {
   //...
   error.setError(getErrorCode(throwable));
   //...
}
private String getErrorCode(Throwable throwable) {
    if (throwable instanceof WebApplicationException && throwable.getMessage() != null) {
        return throwable.getMessage();
    }

    return "unknown_error";
}

And if caused exception is another type of RuntimeException you will get "unknown_error"

Solution (short path):

  1. Extend WebApplicationException and implement your own constructor and getMessage method like that:
public class CustomException extends WebApplicationException {
    private final String message;

    public AbstractUserException(Throwable throwable) {
        // log exception if you want
        this.message = throwable.getMessage();
    }
    
    @Override
    public String getMessage() {
        return message;
    }
}
  1. Wrap the main code of your resource in the try catch block, which always will throw your custom Exception
try {
    // your code
} catch (Exception e) {
    throw new CustomException(e);
}
  1. Voila! You will get a readable error in response

P.S. If you want to go further - you can throw your exception with a complete HTTP Response object, which may contain custom HTTP status code, etc

Upvotes: 1

Related Questions