Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Keycloak adapter Permissions Policy Enforcer. How to set it up

First of all I'm using

  • keycloak-authz-client-3.3.0.Final
  • spring boot 1.5.8.RELEASE
  • spring-boot-starter-security

I've been playing with Keycloak spring adapter exploring the examples since we want to adopt it to our project.

I was able to make it run for Roles easily using this tutorial: https://dzone.com/articles/easily-secure-your-spring-boot-applications-with-k

After that I moved to permissions and that's when it gets trickier (that's also our main goal).

I want to achieve something like described in here (9.1.2): http://www.keycloak.org/docs/2.4/authorization_services_guide/topics/enforcer/authorization-context.html#

  • To get permissions you need to setup in Keycloak Authorization, credentials, and then create Resources or Scopes and Policies to be able to create permissions (it took me a while but I got it working). Testing in the Evaluater everything seems fine.

  • Next step was to get user permissions on the Spring side. In order to do that I had to enable: keycloak.policy-enforcer-config.enforcement-mode=permissive

The moment I enable this I get everytime this exception

java.lang.RuntimeException: Could not find resource.
at org.keycloak.authorization.client.resource.ProtectedResource.findAll(ProtectedResource.java:88)
at org.keycloak.adapters.authorization.PolicyEnforcer.configureAllPathsForResourceServer...
...
Caused by: org.keycloak.authorization.client.util.HttpResponseException: 
Unexpected response from server: 403 / Forbidden

No matter what address I hit in the server.

  • So I started to investigate what was the root of the problem. Looking at some examples how to manually get the permissions I actually got them in postman with the following request: http://localhost:8080/auth/realms/${myKeycloakRealm}/authz/entitlement/${MyKeycloakClient} including the header Authorization : bearer ${accessToken} response was {"rpt": ${jwt token}} that actually contains the permissions

  • So knowing this was working it must be something wrong with the Spring adapter. Investigating a bit further on the Keycloak exception I found that that error was occurring the moment the adapter was getting all the resources. For that it was using the following url: http://localhost:28080/auth/realms/license/authz/protection/resource_set with a different token in the headers (that I copied when debugging) So when I tried it in postman I also got a 403 error, but with a json body:

{ "error": "invalid_scope", "error_description": "Requires uma_protection scope." }

I've enabled and disabled all uma configuration within keycloak and I can't make it work. Can please someone point me into the right direction?

Update

I've now updated Keycloak adapter to 3.4.0.final and I'm getting the following error in the UI:

Mon Nov 20 10:09:21 GMT 2017 There was an unexpected error (type=Internal Server Error, status=500). Could not find resource. Server message: {"error":"invalid_scope","error_description":"Requires uma_protection scope."}

(Pretty much the same I was getting in the postman request)

I've also printed all the user roles to make sure the uma_protection role is there, and it is.

Another thing I did was to disable spring security role prefix to make sure it wasn't a mismatch on the role.

Update 2

Was able to resolve the 403 issue (you can see it in the response below). Still getting problems obtaining KeycloakSecurityContext from the HttpServletRequest

Update 3

Was able to get KeycloakSecurityContext like this:

    Principal principal = servletRequest.getUserPrincipal();
    KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) principal;
    OidcKeycloakAccount auth = token.getAccount();
    KeycloakSecurityContext keycloakSecurityContext = auth.getKeycloakSecurityContext();

    AuthorizationContext authzContext = keycloakSecurityContext.getAuthorizationContext();

The problem now is that the AuthorizationContext is always null.

like image 760
lsp Avatar asked Nov 09 '17 10:11

lsp


1 Answers

I've managed to get it working by adding uma_protection role to the Service Account Roles tab in Keycloak client configuration

Here's the place where it is in Keycloak

More information about it here: http://www.keycloak.org/docs/2.0/authorization_services_guide/topics/service/protection/whatis-obtain-pat.html

Second part of the solution:

It's mandatory to have the security constrains in place even if they don't mean much to you. Example:

keycloak.securityConstraints[0].authRoles[0] = ROLE1
keycloak.securityConstraints[0].securityCollections[0].name = protected
keycloak.securityConstraints[0].securityCollections[0].patterns[0] = /*

Useful demos: https://github.com/keycloak/keycloak-quickstarts

like image 128
lsp Avatar answered Nov 02 '22 05:11

lsp