LaravelでKeycloakを用いてSSOを実現する
以下のように、KeycloakとLaravelとを別のPCで構築し、SSOで連携の上で、Laravel側でログインユーザの属性(カスタム属性を含む)情報を取得するまでの動作を確認した。この記事ではKeycloak側の構築手順も記載しているが、主となるのはLaravel側の手順となる。
- Keycloak
- Windows10
- WSL2
- Laravel
- Windows11
- WSL2
Keycloak設定
以下Keycloak用のPCでの作業となる。
ダウンロードと起動
以下に記述があるようにWSL2上でKeycloakコンテナを開始する。執筆時点で最新は25.0.2であった。docker desktopでも同様のことはできると思うが、使ったことがないのでわからない。
docker run -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak:25.0.2 start-dev
コンテナを停止してもデータを残したい(永続化する)ならば、例えば以下のようにvolumeを指定して、Keycloakコンテナを開始する。
docker run -v keycloak:/opt/keycloak/data -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak:25.0.2 start-dev
以下のようなメッセージがでたら起動している。
2024-08-19 05:59:47,197 WARN [org.keycloak.quarkus.runtime.KeycloakMain] (main) Running the server in development mode. DO NOT use this configuration in production.
admin ログイン
ブラウザで http://localhost:8080 にアクセスする。
Username or email/Passwordにadmin/adminをセットしてSign inする。
ログイン(Sign in)できた。
realm作成
ナビゲーションメニューのKeycloakドロップリストを展開してCreate Realmボタンをクリックする。ちなみにRealmはレルムと読むらしい。
Create realm画面に遷移する。Realm nameテキストボックスにmyrealmと入力しCreateボタンをクリックする。
realm設定の変更
ナビゲーションメニューの Realm settings項目をクリックしてrealm settings画面を開く。
User profile
ページ内のタブ上の<, >ボタンを使ってUser profileタブを探し、選択する。
user_address
Create attributeボタンをクリックして、Create attribute画面を表示する。
以下のように項目をセットしCreateボタンをクリックする。
-
Attribute [Name]:user_address -
Display name:${user_address} -
Multivalued:Off -
Attribute group:None -
Enabled when:Always -
Required field:Off -
Permission Who can edit?User:Off,Admin:On -
Permission Who can view?User:On,Admin:On
gender_code
前項と同様にCreate attributeボタンをクリックして、Create attribute画面を表示する。
以下のように項目をセットしCreateボタンをクリックする。
-
Attribute [Name]:gender_code -
Display name:${gender_code} -
Multivalued:Off -
Attribute group:None -
Enabled when:Always -
Required field:Off -
Permission Who can edit?User:Off,Admin:On -
Permission Who can view?User:On,Admin:On
birth_date
前項と同様にCreate attributeボタンをクリックして、Create attribute画面を表示する。
以下のように項目をセットしCreateボタンをクリックする。
-
Attribute [Name]:birth_date -
Display name:${birth_date} -
Multivalued:Off -
Attribute group:None -
Enabled when:Always -
Required field:Off -
Permission Who can edit?User:Off,Admin:On -
Permission Who can view?User:On,Admin:On
Client作成
ナビゲーションメニューのClients要素をクリックする。
Clients画面に遷移する。
Create clientボタンをクリックして、Create client画面General Settingsページに遷移する。
Client IDテキストボックスに「sample-client」と入力してNextボタンをクリックする。Capability configページに遷移する。
-
Client authentication:On -
Standard flow:On -
Direct access grants:Off
としてNextボタンをクリックする。Login settingsページに遷移する。
Valid redirect URIsテキストボックスおよびWeb originsにも「*」と入力しSaveボタンをクリックする。Client details(sample-client)画面に遷移する。
Credentialの確認
Client details(sample-client)画面で、Credentialタブを選択しタブ内容を表示する。
Client Authenticatorが、「Client id and Secret」であることを確認するとともに、Client Secretの値を別途保存しておく。
なお、ここで設定した sample-client が後に使うKEYCLOAK_CLIENT_IDで、取得したClient secretがKEYCLOAK_CLIENT_SECRETとなる。
mapperを構成
Client details(sample-client)画面で、Client scopesタブを選択すると、client scopeの一覧を表示する。
sample-client-dedicatedをクリックして、sample-client-dedicatedスコープのMapper一覧画面を表示する。
user_address
Configure a new mapperボタンをクリックして、mapper構成ダイアログを表示する。
User Attributeマッパーを選択して、mapper追加画面を表示し以下のように入力する。Saveボタンで保存する。
-
Name:user_address -
User Attribute:user_address(ドロップリストから選択) -
Token Claim Name:user_address -
Claim JSON Type:String -
Add to ID token:On -
Add to Access token:On -
Add to lightweight access token:Off -
Add to userinfo:On -
Add to token introspection:On -
Multivalued:Off -
Aggregate attribute values:Off
Save後、画面上部のパンくずリスト(Clients > Client details > Dedicated scopes > Mapper details)のDedicated scopesリンクをクリックして、dedicated scopes(sample-client-dedicated)のMapper一覧画面を表示する。
gender_code
dedicated scopes(sample-client-dedicated)のMapper一覧画面で、Add mapperドロップリストからBy configurationを選択したのち、前節と同様に、User Attributeマッパーを選択し、mapper追加画面で以下のように入力した後に、Saveボタンで保存する。
-
Name:gender_code -
User Attribute:gender_code(ドロップリストから選択) -
Token Claim Name:gender_code -
Claim JSON Type:String -
Add to ID token:On -
Add to Access token:On -
Add to lightweight access token:Off -
Add to userinfo:On -
Add to token introspection:On -
Multivalued:Off -
Aggregate attribute values:Off
Save後、画面上部のパンくずリスト(Clients > Client details > Dedicated scopes > Mapper details)のDedicated scopesリンクをクリックし、dedicated scopes(sample-client-dedicated)のMapper一覧画面を表示する。
birth_date
dedicated scopes(sample-client-dedicated)のMapper一覧画面で、Add mapperドロップリストからBy configurationを選択したのち、前節と同様に、User Attributeマッパーを選択し、mapper追加画面で以下のように入力した後に、Saveボタンで保存する。
-
Name:birth_date -
User Attribute:birth_date(ドロップリストから選択) -
Token Claim Name:birth_date -
Claim JSON Type:String -
Add to ID token:On -
Add to Access token:On -
Add to lightweight access token:Off -
Add to userinfo:On -
Add to token introspection:On -
Multivalued:Off -
Aggregate attribute values:Off
User作成
ナビゲーションメニューのUsers項目をクリックする。
Users画面に遷移する。
Create new user ボタンをクリックしてCreate user画面に遷移する。例えば以下のように項目を入力する。
-
Required user actions:(空欄) -
Email verified:On -
Username:test000 -
Email:test000@example.com -
First name:t000 -
Last name:test000 -
user_address:札幌市中央区北1条西3丁目3番地 敷島北一条ビル6階 -
gender_code:0 -
birth_date:2002-04-15
Createをクリックして、User details画面に遷移する。
次に、User details画面のCredentialsタブをクリックしてパスワードを追加する。ここでは、TemporaryスイッチはOffにしておく。
Saveボタンをクリックすると確認ダイアログが出現するので、Save passwordを選択する。
ログアウト
adminドロップリストをクリックしSign outを選択、ログアウトする。
ログイン
上述のURLにアクセスするとログインダイアログが出現する。画面上部のロゴ領域がMYREALMになっている。
test000/yourpasswordを入力してSign inをクリックすると、先ほど設定した個人情報を確認できる。
またプライベートウィンドウ(シークレットウィンドウ)などで、別途admin console( http://localhost:8080 )にアクセスし、test000ユーザーのSessionsタブを確認すると、セッションができていることを確認できる。
別PCからアクセス
以下記事にならって、Keycloakを起動したPCに外部(Laravelを起動するPC)からアクセスできるように設定しておく。
なおこのPCの外部IPをa.b.c.dのように以下記載する。実際は192.168.0.18のようなものとなる。
Laravel
ダウンロードと初期設定
ここに記載の通り(docker)にすすめる(Breezeをインストールしてログインできるところまで)。
> curl -s "https://laravel.build/chirper" | bash
> cd chirper
> ./vendor/bin/sail up -d
> ./vendor/bin/sail artisan migrate
> ./vendor/bin/sail composer require laravel/breeze --dev
> ./vendor/bin/sail php artisan breeze:install blade
> ./vendor/bin/sail npm run dev
# Ctfl + Cでキャンセル
キャンセル前にブラウザでlocalhostにアクセスすれば、以下のような画面を確認できる。
Socialite Providersのインストール
つづいてSocialiteProvidersをインストールする。
vendor/bin/sail composer require socialiteproviders/keycloak
以降、Laravel側にコードを追加していく。
.envに以下の項目を追加
KEYCLOAK_CLIENT_ID="sample-client"
KEYCLOAK_CLIENT_SECRET="xxxxxxxx"
KEYCLOAK_REDIRECT_URI="http://localhost/auth/keycloak/callback"
KEYCLOAK_BASE_URL="http://a.b.c.d:8080/"
KEYCLOAK_REALM="myrealm"
-
KEYCLOAK_CLIENT_SECRETの"xxxxxxxx"は、実際の値に置き換える。 -
KEYCLOAK_BASE_URLのa.b.c.dはKeycloakを立ち上げたPCのIPアドレスに置き換える。
config/services.phpに以下追加
'ses' => [
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
],
// ここから追加
'keycloak' => [
'client_id' => env('KEYCLOAK_CLIENT_ID'),
'client_secret' => env('KEYCLOAK_CLIENT_SECRET'),
'redirect' => env('KEYCLOAK_REDIRECT_URI'),
'base_url' => env('KEYCLOAK_BASE_URL'),
'realms' => env('KEYCLOAK_REALM'),
],
// ここまで追加
Laravel10以前の場合
Laravel10以前の場合の詳細を見る
config/app.phpに以下追加
/* 前略 */
'providers' => ServiceProvider::defaultProviders()->merge([
/* 中略 */
App\Providers\RouteServiceProvider::class,
/* ここから追加 */
//Laravel\Socialite\SocialiteServiceProvider::class,
\SocialiteProviders\Manager\ServiceProvider::class,
/* ここまで追加 */
])->toArray(),
/* 後略 */
app/Providers/EventServiceProvider.php
以下を追加
protected $listen = [
/* ここから */
\SocialiteProviders\Manager\SocialiteWasCalled::class => [
\SocialiteProviders\Keycloak\KeycloakExtendSocialite::class.'@handle',
],
/* ここまで */
Registered::class => [
SendEmailVerificationNotification::class,
],
];
Laravel11以上の場合
bootstrap/provider.phpに以下追加
<?php
return [
App\Providers\AppServiceProvider::class,
/* ここから追加 */
\SocialiteProviders\Manager\ServiceProvider::class,
/* ここまで追加 */
];
app/Providers/AppServiceProvider.phpに以下追加
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
/* ここから追加 */
use Illuminate\Support\Facades\Event;
/* ここまで追加 */
bootメソッドに以下コードを追加する。
/**
* Bootstrap any application services.
*/
public function boot(): void
{
/* ここから追加 */
Event::listen(function (\SocialiteProviders\Manager\SocialiteWasCalled $event) {
$event->extendSocialite('keycloak', \SocialiteProviders\Keycloak\Provider::class);
});
/* ここまで追加 */
}
app/Http/Controllers/KeycloakLoginController.php
以下内容のコントローラを新規追加する。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Auth;
use Socialite;
use App\Models\User;
class KeycloakLoginController extends Controller
{
public function redirectToKeycloak()
{
return Socialite::driver('keycloak')->redirect();
}
public function handleKeycloakCallback()
{
$keycloakUser = Socialite::driver('keycloak')->stateless()->user();
$user = User::where('email', $keycloakUser->email)->first();
if ($user==null) {
$user = $this->createUser($keycloakUser);
}
Auth::login($user, true);
return redirect('/dashboard');
}
public function createUser($keycloakUser)
{
dd ( $keycloakUser );
$user = User::create([
'name' => $keycloakUser->user['name'],
'email' => $keycloakUser->user['email'],
'password' => Hash::make(uniqid()),
]);
return $user;
}
}
routes/web.php
以下ルートを追加する。
<?php
use App\Http\Controllers\ProfileController;
/* ここから */
use App\Http\Controllers\KeycloakLoginController;
/* ここまで */
use Illuminate\Support\Facades\Route;
// redirect to keycloak
Route::get('/auth/keycloak', [KeycloakLoginController::class, 'redirectToKeycloak'])
->name('login.keycloak');
// after authentication
Route::get('/auth/keycloak/callback', [KeycloakLoginController::class, 'handleKeycloakCallBack'])
->name('login.keycloak.callback');
resources\views\auth\login.blade.php
以下コードを追加し、ログイン画面にKeycloakのアイコンを加える。
<x-primary-button class="ml-3">
{{ __('Log in') }}
</x-primary-button>
</div>
</form>
<!-- ここから -->
<div class="flex items-center justify-end mt-4">
<a href="{{ route('login.keycloak') }}" class="ml-3 inline-flex items-center">
<img src="https://upload.wikimedia.org/wikipedia/commons/2/29/Keycloak_Logo.png" style="margin-left: 3em; width: 64px; height: 64px">
</a>
</div>
<!-- ここまで -->
</x-guest-layout>
SSO動作確認
Keycloakログイン済みの場合
以下Laravelを立ち上げたPCにて操作する。
-
まず、Keycloakのセッション情報をブラウザに保存するため、Keycloakにログインする。
-
プライベートモードなどで別途ブラウザを立ち上げて、admin consoleにログインしてセッションがあることを確認する。
-
http://a.b.c.d:8080
-
a.b.c.dはKeycloakを立ち上げているPCのIPアドレスに置き換える。
-
- レルム:myrealm
- Clients --> sample-client --> Sessions
- なにかセッションがあればOK
-
http://a.b.c.d:8080
-
1項とおなじブラウザでローカルのLaravelにアクセスする。
-
画面上の
Log inリンクからログイン画面に遷移し、LOG INボタン下のKeycloakアイコンを選択する(画面上のEmail欄やPassword欄にはなにも入力しない)。

-
なお
app/Http/Controllers/KeycloakLoginController.phpに追加したコードからdd ( $keycloakUser );の行をコメントアウトすると以下の画面となる。

-
Laravel側で
Log outする。- ちなみに、Laravel側UIで
Log outを操作しても(Laravel側で未実装のため)Keycloak側ではログアウトしていない。
- ちなみに、Laravel側UIで
Keycloak未ログインの場合
- Keycloak未ログインの状態で、ローカルのLaravelにアクセスする。
- 画面上のLoinリンクからログイン画面に遷移し、
LOG INボタン下のKeycloakアイコンを選択する。 - リダイレクトが発生し、Keycloakのログイン画面を表示する。
-
test000/yourpasswordでログインし、前節5項(あるいは6項)と同様の画面を得ることができる。
まとめ
この記事では、Keycloakを使ったSSOおよびユーザ情報の取得をLaravelで実現する方法をまとめた。
Keycloakの構成は、試行錯誤で行ったものであるので本格的に使う場合は別書を参考にしてほしい。



































