Fran b
Fran b

Reputation: 3036

How to evaluate permissions with Keycloak authzClient?

I have a protected resource on Keycloak created via remote API with this code:

    private fun ProtectedEntity.protect(location: URI, principal: Principal) {
        val newResource = ResourceRepresentation()
        newResource.name = this.id
        newResource.displayName = this.name
        newResource.type = "urn:$appName:resources:${this.javaClass.simpleName.toLowerCase().replace("entity", "")}"
        newResource.owner = ResourceOwnerRepresentation(this.creator)
        newResource.ownerManagedAccess = true
        newResource.uris = setOf(location.path.toString())
        authzClient.protection().resource().create(newResource)
    }

The resource owner is the user who invoked the method and he can manage his own resources.

Now I have to check if a user has permission to access a resource and if not, I guess I should return a ticket in the case the user would like request access to the resource. I tried with this but authorize() throws "Error creating permission ticket".

override fun read(id: ID, principal: Principal): Mono<ResponseEntity<E>> {
        val currentUserToken = principal!!.getCurrentUserToken()
        val resource = authzClient.protection().resource().findByName(id.toString(), currentUserToken.getUsername())
        val token = currentUserToken.tokenValue
        val request = AuthorizationRequest()
        request.addPermission(resource.id)
        request.setRpt(token)

        // This returns Error creating permission ticket !?
        val response = authzClient.authorization().authorize(request)
        val result = authzClient.protection().introspectRequestingPartyToken(response.token)
        println(result.active)
        if (result.active) {
           return super.read(id, principal)
        } else throw RuntimeException("Result token RPT is not active!")
}

How I would delegate on Keycloak permission evaluating using authzClient?

Upvotes: 2

Views: 693

Answers (1)

Fran b
Fran b

Reputation: 3036

The solution is to replace .findByName() by .findByUri(). This endpoint not take into account the resource's owner. I created a gist just in case someone else may need it: ResourceAccessKeycloakWebFilter

Upvotes: 1

Related Questions