lsp
lsp

Reputation: 171

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

First of all I'm using

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#

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.

{ "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.

Upvotes: 10

Views: 22050

Answers (3)

emreozdem1r
emreozdem1r

Reputation: 1

If you faced "java.lang.RuntimeException: Could not find resource" error and you are using Keycloak docker container, The error can be because of this. I dont have enough information about docker. Hence I download keycloak as a zip file and run it. It works properly.

Upvotes: 0

lsp
lsp

Reputation: 171

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

Upvotes: 6

Alexandr Angin
Alexandr Angin

Reputation: 1

This code works for me:

HttpServletRequest request = ...; // obtain javax.servlet.http.HttpServletRequest
Principal userPrincipal = request.getUserPrincipal();
KeycloakPrincipal < KeycloakSecurityContext > keycloakPrincipal =
  (KeycloakPrincipal < KeycloakSecurityContext > ) userPrincipal;
KeycloakSecurityContext securityContext =
  keycloakPrincipal.getKeycloakSecurityContext();

Upvotes: 0

Related Questions