robsontenorio / laravel-keycloak-guard

🔑 Simple Keycloak Guard for Laravel
MIT License
434 stars 141 forks source link

Confused by resource_access and allowed_resources #22

Closed bbeng89 closed 4 years ago

bbeng89 commented 4 years ago

Hello, It looks like your package is going to work great for my needs, but I'm really confused by how the resource_access check is supposed to work. Please note that I'm very new to keycloak and this terminology, but I'll do my best to describe my issue.

In Keycloak I created a client test-app-js and have added the client roles "user", "manager", and "superuser".

I've set up a mapper to add the users client roles to the token. The default Token Claim Name for the mapper is resource_access.${client_id}.roles. When I inspect the token, I can see the role is getting added in this format:

Screen Shot 2020-05-07 at 3 58 37 PM

Initially I was trying to set the allowed_resources to my roles, like "allowed_resources" => "user,manager,superuser", but I always get the error:

The decoded JWT token has not a valid resource_access allowed by API.

After some digging I found this is the part of the code that checks the resource access:

https://github.com/robsontenorio/laravel-keycloak-guard/blob/310d6281f47a05c87b109666064b4b2a2c045b87/src/KeycloakGuard.php#L160-L168

The line that confuses me is:

$token_resource_access = array_keys((array)($this->decodedToken->resource_access ?? []));

So my question is: is the intention with allowed_resources to restrict clients? Because the only way I've been able to get it to work is to set "allowed_resources" => "test-app-js" (my client name), which works because that is the key of the first array inside resource_access. I guess I was just confused if this was the intended functionality, or if I'm doing something wrong.

Thanks!

ghost commented 4 years ago

Hi @bbeng89,

I was currently working on the project and saw your request. I'm not sure if I get your question right but with the resource_access you can protect your service access. Implementation-wise the library just checks for the presence of resource_access.<your-client>.roles.<your-defined-role> in the JWT token. How the information gets there is subject to configuration in Keycloak and depends on your scenario. So you can assign the client-role as generic role for the client or to particular users, roles, groups, ... It is however necessary to configure your client with the proper scope, that the roles are present.

I know, the answer isn't too precise but maybe helps.

Cheers!

alexisverardo commented 4 years ago

check the jwt token returned by keycloak on this page https://jwt.io/#debugger-io and look at the "resource_access" attribute: { "account": { "roles": [ "manage-account", "manage-account-links", "view-profile" ] }, "test": { "roles": [ "TEST" ] } will show you the available reosource_access and put one in the environment variable KEYCLOAK_ALLOWED_RESOURCES

SaldanhaASCS commented 4 years ago

Olá, Parece que seu pacote vai funcionar muito bem para minhas necessidades, mas estou muito confuso sobre como a resource_accessverificação deve funcionar. Observe que sou muito novo no keycloak e nessa terminologia, mas farei o possível para descrever meu problema.

No Keycloak, criei um cliente test-app-jse adicionei as funções de cliente "usuário", "gerente" e "superusuário".

Eu configurei um mapeador para adicionar as funções de cliente dos usuários ao token. O nome de reivindicação de token padrão para o mapeador é resource_access.${client_id}.roles. Quando inspeciono o token, posso ver que a função está sendo adicionada neste formato:

Captura de tela 07-05-2020 às 3 58 37 PM

Inicialmente, eu estava tentando definir o allowed_resourcespara minhas funções, tipo "allowed_resources" => "user,manager,superuser", mas sempre recebo o erro:

O token JWT decodificado não tem uma resource_accesspermissão válida pela API.

Após algumas pesquisas, descobri que esta é a parte do código que verifica o acesso ao recurso:

https://github.com/robsontenorio/laravel-keycloak-guard/blob/310d6281f47a05c87b109666064b4b2a2c045b87/src/KeycloakGuard.php#L160-L168

A linha que me confunde é:

$ token_resource_access = array_keys (( array ) ( $ this -> decodedToken -> resource_access ?? []));

Então minha pergunta é: a intenção é allowed_resourcesrestringir clientes? Porque a única maneira de fazer funcionar é definir "allowed_resources" => "test-app-js"(nome do meu cliente), que funciona porque essa é a chave do primeiro array interno resource_access. Acho que fiquei confuso se essa era a funcionalidade pretendida ou se estou fazendo algo errado.

Obrigado!

Your .env KEYCLOAK_ALLOWED_RESOURCES=test-app-js