agrodata/keycloak-authz

🔑 Keycloak Guard Authorization for Laravel/Lumen

This package's canonical repository appears to be gone and the package has been frozen as a result.

v1.2 2022-01-03 13:08 UTC

This package is auto-updated.

Last update: 2022-12-31 00:19:35 UTC


README

alt text

Laravel/Lumen Keycloak Authz

Este pacote foi criado para realizar a autenticação e autorização do keycloak para API Laravel/Lumen.

Criado apartir do pacote laravel-keycloak-guard, com adição das funcionalidades:

  • cadastro dos dados do usuário em banco local
  • gerenciamento de autorização/permissões

Requisitos

✔️ API construída em Laravel/Lumen.

✔️ Você não poderá usar o Laravel Passport, pois, o Keycloak fará o que é preciso.

✔️ O projeto frontend deve ser separado do backend.

✔️ O frontend fará a autenticação direto no Servidor Keycloak e apenas enviar o token para o backend.

✔️ O Frontend mantem o token JWT do Servidor Keycloak.

✔️ O frontend faz solicitações para a API, com esse token.

✔️ Para usar as permissões e a middleware can o keycloak client deve ter o recurso de autorização ativa e configurada.

(x) Se você não tem esses requisitos, provavelmente deverá utilizar https://socialiteproviders.com/Keycloak or https://github.com/Vizir/laravel-keycloak-web-guard

  1. O Frontend realiza a autenticação com o servidor Keycloak e obtem o AccessToken.

  2. Frontend faz requisição enviando o access token para a api.

  3. A API valida o accessToken (através do Keycloak Guard).

    • Valida a assinatura do token.
    • Valida a estrutura do token.
    • Valida o tempo de expiração do token.
    • Valida se a api permite os resource access do token.
    • Verifica se o token contém permissões/autorizações

    3.1 Se o token é valido, Atualiza os dados do usuário no banco de dados local.

  4. Verifica as permissões do usuário (se search_permission for ativa)

  5. Valida as permissões via middleware :can (se search_permission for ativa)

  6. Return response

Instalação

Laravel / Lumen

Instale o pacote

composer require agrodata/keycloak-authz

para Lumen

Registre o Provider no seu arquivo boostrap `bootstrap/app.php`

Adicione a seguinte linha em na final do arquivo.

$app->register(\KeycloakGuard\KeycloakGuardServiceProvider::class);

Para utilizar Facades, descomente a linha `$app->withFacades();no seu arquivobootstrap/app.php`

Configuração

Keycloak Guard

A configuração do Keycloak Guard pode ser feita a partir do arquivo .env. ⚠️ Certifique-se de que todas as strings estejam com aspas duplas.

Opcional: você pode publicar o arquivo de configuração.

php artisan vendor:publish  --provider="Agrodata\KeycloakAuthz\KeycloakGuardServiceProvider"
<?php

return [  
  'realm_public_key' => env('KEYCLOAK_REALM_PUBLIC_KEY', null),

  'load_user_from_database' => env('KEYCLOAK_LOAD_USER_FROM_DATABASE', true),

  'user_provider_credential' => env('KEYCLOAK_USER_PROVIDER_CREDENTIAL', 'username'),

  'token_principal_attribute' => env('KEYCLOAK_TOKEN_PRINCIPAL_ATTRIBUTE', 'preferred_username'),

  'append_decoded_token' => env('KEYCLOAK_APPEND_DECODED_TOKEN', false),

  'allowed_resources' => env('KEYCLOAK_ALLOWED_RESOURCES', null),
  
  /**
   * autorization attributes
   */
   'search_permissions' => env('KEYCLOAK_SEARCH_PERMISSIONS', true),

   'client_id' => env('KEYCLOAK_CLIENT_ID', null),

   'token_endpoint' => env('KEYCLOAK_TOKEN_ENDPOINT', null),
];

✔️ realm_public_key

Required.

The Keycloak Server realm public key (string).

How to get realm public key? Click on "Realm Settings" > "Keys" > "Algorithm RS256" Line > "Public Key" Button

✔️ load_user_from_database

Obrigatório. padrão true.

Se você não possuí uma tabela users você deve desabilitar este atributo. load_user_from_database Irá verificar se você já possúi este usuário no banco de dados, realizar a atualização dos dados e retorna-los para o objeto de Autenticação (Auth::class). Se for habilitado, deverá trabalhar junto com o atributo user_provider_credential e token_principal_attribute.

✔️ user_provider_credential

Obrigatório. padrão username.

O campo da tabela "users" que deve conter um identificador único (ex. username, email, nickname). Será confrontado com o atributo token_principal_attribute, enquanto é realizada a autenticação.

✔️ token_principal_attribute

Obrigatório. Default is preferred_username.

Propriedade do token JWT que será utilizado como identificador único. Será confrontando com o atributo user_provider_credential, durante a autenticação.

✔️ append_decoded_token

padrão false.

Anexa o token decodificado (com informações do usuário) em $user->token. Utilizado para pegar informações como: perfil, grupos e outras informações anexadas ao JWT. Se for false, você também pode obtelo via Auth::token().

✔️ allowed_resources

Obrigatório

Normalmente, sua API deve lidar com um resource_access . Mas, se você lida com múltiplos, apenas use uma lista separada por vírgulas de recursos permitidos aceitos pela API. Este atributo será confrontado com o atributo resource_access do token JWT, durante a autenticação.

✔️ search_permission

Obrigatório

padrão false.

Verifica se o Token JWT possuí informações de permissionamento/autorização. Se não possuir irá buscar os dados de autorização no Servidor Keycloak, para registrar as permissões e proteger as rotas através da middleware ":can". Depende dos atributos token_endpoint e client_id serem informados corretamente.

✔️ client_id

Optional

padrão null.

Identificação do client no servidor keycloak que possuí o modulo de autorização/permissões ativa.

✔️ token_endpoint

padrão null.

Optional

URL para buscar informações de autorização do token no servidor keycloak.

Laravel Auth

Altere em config/auth.php

...
'defaults' => [
        'guard' => 'api', # <-- For sure, i`m building an API
        'passwords' => 'users',
    ],
    
    ....
    
    'guards' => [
        'api' => [
            'driver' => 'keycloak', # <-- Set the API guard driver to "keycloak"
            'provider' => 'users',
        ],
    ],

Laravel Routes

Protegerá as rotas pela validação do token, altere em routes/api.php

// public endpoints
Route::get('/hello', function () {
    return ':)';
});

// protected endpoints
Route::group(['middleware' => 'auth:api'], function () {
    Route::get('/protected-endpoint', 'SecretController@index');
    // more endpoints ...
});

Lumen Routes

Protegerá as rotas pela validação do token, altere em routes/web.php

// public endpoints
$router->get('/hello', function () {
    return ':)';
});

// protected endpoints
$router->group(['middleware' => 'auth'], function () {
    $router->get('/protected-endpoint', 'SecretController@index');
    // more endpoints ...
});

API

Implementação simples do Keycloak Guard Illuminate\Contracts\Auth\Guard. Portanto, todos os métodos padrão do Laravel estarão disponíveis. Ex: Auth::user() retornará o usuário autenticado.

métodos padrões:

  • check()
  • guest()
  • user()
  • id()
  • validate()
  • setUser()

métodos do Keycloak Guard:

  • token()

Ex: Auth::token() retorna o token decodificado completo.

  • hasRole('some-resource', 'some-role'): Verifica se o usuário tem algum perfil específico.

Ex:

'resource_access' => [
  'myapp-backend' => [
      'roles' => [
        'myapp-backend-role1',
        'myapp-backend-role2'
      ]
  ],
  'myapp-frontend' => [
    'roles' => [
      'myapp-frontend-role1',
      'myapp-frontend-role2'
    ]
  ]
]
Auth::hasRole('myapp-backend', 'myapp-backend-role1') // true
Auth::hasRole('myapp-frontend', 'myapp-frontend-role1') // true
Auth::hasRole('myapp-backend', 'myapp-frontend-role1') // false