marionassef/laravel-keycloak-guard

🔑 Laravel 的简单 Keycloak 守卫

1.3.7 2022-07-21 14:40 UTC

This package is auto-updated.

Last update: 2024-09-21 20:25:55 UTC


README

 

简单 Laravel/Lumen Keycloak 守卫

此包帮助您在基于 Keycloak 服务器生成的 JWT 令牌的基础上,对 Laravel API 上的用户进行身份验证。

要求

✔️ 我正在用 Laravel 构建 API。

✔️ 我不会使用 Laravel Passport 进行身份验证,因为 Keycloak 服务器将完成这项工作。

✔️ 前端是一个独立的项目。

✔️ 前端用户直接在 Keycloak 服务器上认证以获取 JWT 令牌。这个过程与 Laravel API 没有关系。

✔️ 前端保留来自 Keycloak 服务器 的 JWT 令牌。

✔️ 前端使用该令牌向 Laravel API 发送请求。

💔 如果您的应用程序不符合要求,可能您正在寻找 https://socialiteproviders.com/Keycloakhttps://github.com/Vizir/laravel-keycloak-web-guard

流程

  1. 前端用户在 Keycloak 服务器上认证

  2. 前端用户获取 JWT 令牌。

  3. 在另一个时刻,前端用户使用该令牌向 Laravel API 上的受保护端点发送请求。

  4. Laravel API(通过 Keycloak 守卫)处理它。

    • 验证令牌签名。
    • 验证令牌结构。
    • 验证令牌过期时间。
    • 验证我的 API 是否允许从令牌中进行 资源访问
  5. 如果一切正常,在数据库中找到用户并在我的 API 上对其进行认证。

  6. 可选地,用户可以在 API 用户数据库中创建/更新。

  7. 返回响应

安装

Laravel / Lumen

需要此包

composer require robsontenorio/laravel-keycloak-guard

Lumen 仅支持

在您的 bootstrap/app.php 应用程序启动文件中注册提供者

在文件底部 "注册服务提供者" 部分中添加以下行。

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

对于外观,在您的 bootstrap/app.php 应用程序启动文件中取消注释 $app->withFacades();

配置

Keycloak 守卫

Keycloak 守卫的配置可以从 Laravel .env 文件中处理。⚠️ 确保所有字符串 都已缩进。

可选地,您可以发布配置文件。

php artisan vendor:publish  --provider="KeycloakGuard\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_custom_retrieve_method' => null,

  '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)
];

✔️ realm_public_key

必需。

Keycloak 服务器领域公钥(字符串)。

如何获取领域公钥?点击 "领域设置" > "密钥" > "算法 RS256" 行 > "公钥" 按钮

✔️ load_user_from_database

必需。默认为 true

如果您没有 users 表,则必须禁用此功能。

它从数据库中获取用户并将值填充到认证用户对象中。如果启用,它将与 user_provider_credentialtoken_principal_attribute 一起工作。

✔️ user_provider_custom_retrieve_method

默认为 null

如果您有一个 users 表,并且希望它根据令牌进行更新(创建或更新用户),则可以通知自定义 UserProvider 上的自定义方法,该方法将代替 retrieveByCredentials 调用,并将完整的解码令牌作为参数接收,而不仅仅是凭据(默认)。
这允许您在匹配和交付经过身份验证的用户对象之前,以您希望的方式自定义与数据库交互的方式,并且所有信息都包含在(有效的)访问令牌中。有关自定义UserProviders的更多信息,请参阅Laravel关于此的文档

如果使用此功能,显然,将忽略为user_provider_credentialtoken_principal_attribute定义的值。

✔️ user_provider_credential

必需。默认为username

"users"表中包含用户唯一标识符的字段(例如,用户名、电子邮件、昵称)。在身份验证时,此字段将与token_principal_attribute属性进行对比。

✔️ token_principal_attribute

必需。默认为preferred_username

JWT令牌中包含用户标识符的属性。在身份验证时,此属性将与user_provider_credential属性进行对比。

✔️ append_decoded_token

默认为false

将完整的解码JWT令牌附加到经过身份验证的用户($user->token)。如果您需要知道JWT令牌中持有的角色、组和其他用户信息,这很有用。即使选择false,您也可以使用Auth::token()获取它,请参阅API部分。

✔️ allowed_resources

必需

通常您的API应该处理一个resource_access。但如果您处理多个,只需使用逗号分隔的列表,列出API接受的允许资源。在身份验证时,此属性将与JWT令牌中的resource_access属性进行对比。

Laravel Auth

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

只需保护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

只需保护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

简单的Keycloak Guard实现了Illuminate\Contracts\Auth\Guard。因此,所有Laravel默认方法都将可用。例如:Auth::user()返回经过身份验证的用户。

默认方法

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

Keycloak Guard方法

  • token()

例如:Auth::token()返回经过身份验证的用户完整的解码JWT令牌

  • hasRole('some-resource', 'some-role'):检查经过身份验证的用户是否在某个资源中具有特定角色。

例如:使用此有效载荷

'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

联系

Twitter @robsontenorio