colq2 / laravel-keycloak
laravel 的 keycloak 适配器。
Requires
- php: ^7.1
- ext-json: *
- illuminate/auth: ^5.8
- illuminate/cache: ^5.8
- illuminate/contracts: 5.8
- illuminate/session: ^5.8
- illuminate/support: ^5.8
- lcobucci/jwt: ^3.2
- stevenmaguire/oauth2-keycloak: dev-master
Requires (Dev)
- orchestra/testbench: ~3.7
- orchestra/testbench-dusk: ^3.7
- phpunit/phpunit: ^7.0
This package is auto-updated.
Last update: 2024-09-15 00:57:13 UTC
README
这是一个易于使用的 laravel keycloak 适配器。
这仍然处于开发阶段,尚未准备好用于生产。
欢迎对此项目做出贡献。
待办事项
[ ] 允许使用不同的用户存储,如 Cache、Session、Eloquent、Database 等。
安装
composer require colq2/laravel-keycloak
发布配置和迁移
php artisan vendor:publish --provider=colq2\Keycloak\KeycloakServiceProvider
此项目重新定义了用户模型和迁移。不需要密码重置表。此外,我们还需要在用户上添加其他属性(这些属性大多是 openid-connect 定义的属性)。
- id
- sub
- username
- name
- picture
- roles
如果您想将 keycloak 作为唯一的认证方式,可以删除项目中所有迁移。
将以下内容添加到 .env 文件中
KEYCLOAK_USER_MODEL=
KEYCLOAK_BASE_URL=
KEYCLOAK_REALM=
KEYCLOAK_CLIENT_ID=
KEYCLOAK_CLIENT_SECRET=
KEYCLOAK_REDIRECT=/callback
用法
控制器
<?php
class LoginController extends \Illuminate\Routing\Controller
{
/**
* @var \colq2\Keycloak\Contracts\Authenticator
*/
private $authenticator;
public function __construct(\colq2\Keycloak\Contracts\Authenticator $authenticator)
{
$this->authenticator = $authenticator;
}
public function handleRedirect()
{
$this->authenticator->handleRedirect();
}
public function handleCallback()
{
$this->handleCallback();
$user = auth()->user();
}
}
路由
Route::get('login', 'LoginController@handleRedirect');
Route::get('callback', 'LoginController@handleCallback');
中间件
此包附带 CheckRealmAccess 和 CheckResourceAccess 中间件。您可以将它们添加到 app/Http/Kernel.php 文件中。
protected $routeMiddleware = [
// ...
'realm_access' => \colq2\Keycloak\Http\Middleware\CheckRealmAccess::class,
'resource_access' => \colq2\Keycloak\Http\Middleware\CheckResourceAccess::class,
];
然后您可以使用中间件
领域访问中间件
Route::get('post/{post}', function(Post $post) {
// The current user has role1 and role2 in the realm
})->middleware('realm_access:role1,role2');
资源访问中间件
Route::get('post/{post}', function(Post $post) {
// The current user has role1 and role2 in client1 in the realm
})->middleware('resource_access:client1,role1,role2');
自定义用户
自定义 keycloak 用户保存属性:id、sub、username、name、email 和 picture
要自定义此功能,您应该执行以下三个步骤
- 更新迁移
- 更新用户模型
- 提供自定义服务
更新迁移
在 create_user_table 迁移中,您可以添加或删除所需的属性。默认情况下,您可以使用 openid-connect 规范中定义的所有声明。
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('sub')->unique();
$table->string('username')->nullable();
$table->string('email')->nullable();
$table->string('name')->nullable();
$table->string('picture')->nullable();
$table->json('roles')->nullable();
$table->rememberToken();
$table->timestamps();
});
}
更新用户模型
定义了所需属性后,您必须在 fillable 属性中定义相同的属性。
<?php
namespace colq2\Keycloak;
use colq2\Keycloak\Contracts\Roles\HasRoles;
use Illuminate\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\Access\Authorizable;
class KeycloakUser extends Model implements AuthenticatableContract, AuthorizableContract, HasRoles
{
use Authenticatable, Authorizable;
protected $table = 'users';
protected $fillable = [ 'sub', 'username', 'name', 'email', 'picture', 'roles' ];
protected $casts = [ 'roles' => 'array' ];
protected $hidden = [ 'remember_token' ];
public function getAllRoles(): array
{
return $this->roles;
}
}
提供自定义用户服务
openid-connect 声明必须解析为自定义属性。只需构建一个新的类并扩展默认用户服务。然后更新应用绑定到您的用户服务。
在 CustomUserService 中
<?php
namespace colq2\Keycloak\Examples;
use colq2\Keycloak\KeycloakUserService;
class CustomUserService extends KeycloakUserService
{
/**
* @param array $user
* @return array|\colq2\Keycloak\KeycloakUser
*/
public function mapUser(array $user): array
{
// Do whatever you need
$user['username'] = $user['preferred_username'];
// And return it
return $user;
}
}
并将其绑定到您的应用程序中 AppServiceProvider
**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
$this->app->singleton(UserService::class, function($app){
return new CustomUserService($app['config']->get('keycloak.model'));
});
}