株式会社 Vitalizeで webエンジニアをしている @nagaemon です。
現在は長野の支社にお世話になっており、現在はエンジニア + 地方創生事業に携わっています。
好きな言語はrubyです。
keycloakとは
Keycloakはオープンソースのアイデンティティ・アクセス管理ソフトウェアです
概要はこちらの記事がわかりやすいので、ご覧ください。
Keycloakとは
今回の目的
Qiitaでもkeycloak関連の記事はありますが、 Keycloak ✖️ Railsの記事がなかったので、自分の備忘録も兼ねて記事を書こうと思いました。
今回はkeycloakのOIDC(openIDconnect)を使って実際にrailsを用いてログイン機能が作れるのかどうかを試してみます。
サンプルファイル
開発環境
Keycloak
- keycloak: 21.0.2
- database: mysql:8.0.33
Rails
- Rails 7.0.4
その他
- Docker 24.0.2
Keycloak側の設定
Dockerでの立ち上げ方法
keycloakのGeting started内のDockerを参考にDocker-composeを作成。
version: '3.8'
volumes:
mysql_data:
driver: local
services:
mysql:
image: mysql:8.0.33
container_name: mysql
volumes:
- mysql_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: keycloak
MYSQL_USER: keycloak
MYSQL_PASSWORD: password
ports:
- 3306:3306
keycloak:
image: quay.io/keycloak/keycloak:21.0.2
container_name: keycloak
environment:
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin
KC_DB: mysql
KC_DB_URL: jdbc:mysql://mysql:3306/keycloak
KC_DB_URL_DATABASE: keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: password
KC_HOSTNAME_STRICT: 'false'
KC_HTTP_ENABLED: 'true'
KC_HOSTNAME_STRICT_HTTPS: 'false'
ports:
- 8080:8080
command:
- "start"
- "--auto-build"
$ docker compose up
コマンド実行後にhttp://localhost:8080 にアクセス
Administration Console にアクセスしましょう
ユーザ名とパスワードはdocker-composeファイルで指定していた ”admin" を使いましょう
レルム、クライアント、ユーザーの作成
レルム クライアント ユーザーはkeycloakのGeting started内のDockerでの立ち上げ方法に記載されてある方法を参考にしましょう。命名について、自分は今回下記のように作成しました。
- realm: demo-realm
- clients: demo-client
- user: demo-user
加えて、今回はローカルで試すので
Valid redirect URIs は http://127.0.0.1:3000/*
Set Web origins は http://127.0.0.1:3000
に変更しておきましょう
クライアント認証の設定
上記の設定に加えて、Rails等のサーバーサイドアプリケーションでの認証ですので。OIDCプロバイダ(keycloak)とのアクセス方法をConfidential Access Type (機密アクセスタイプ)に変更しましょう
具体的には、クライアント(サイドバー) → 設定タブ選択 → Capability config内のクライアント認証をONにしてもらえればOKです。
その後、クレデンシャルタブ内のクライアント認証を「Client Id and Secret」を選択。
クライアントシークレットをどこかにメモしておきましょう。Railsの設定時に利用します。
Rails側の設定
適当にディレクトリを作成後
$ cd dir #=> 自分の好きなディレクトリ
$ rails new .
Gemの利用
今回は
- gem 'omniauth-keycloak'
- gem "omniauth-rails_csrf_protection"
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby "3.2.2"
# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
gem "rails", "~> 7.0.6"
#---------省略---------
gem 'omniauth-keycloak'
gem 'omniauth-rails_csrf_protection'
# ↑↑上記を記入↑↑
group :development, :test do
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
gem "debug", platforms: %i[ mri mingw x64_mingw ]
end
#---------省略---------
その後
bundle install
omniauth自体の使い方はomniauthのgithubページに懇切丁寧に書かれています。
そちらを参考に少しいじります。
provider :keycloak_openid,
'demo-client', #=> クライアント名
'xxxxxxxxxxxxxxxx',#=> 事前にメモしておいたシークレットコード
client_options: {base_url: '',#=> これをつけないと/authに飛んでしまうので、つける
site: 'http://localhost:8080',#=> サイト
realm: 'demo-realm'},#=> レルム名
name: 'keycloak'
end
Rails.application.routes.draw do
root "static_pages#top"
get '/auth/:provider/callback', to: 'sessions#create'
get '/login', to: 'sessions#new'
get '/top', to: 'static_pages#top'
get '/user', to: 'static_pages#user'
delete '/logout', to: 'sessions#delete'
end
/auth/:provider/callback
とエンドポイントを指定すると、omniauthがよしなにやってくれます。
sessions_controllerは下記のように作りました。
class SessionsController < ApplicationController
protect_from_forgery
def new
render :new
end
def create
user_info = request.env['omniauth.auth']
uid = user_info&.uid
email = user_info&.info&.email
@user = User.find_or_create_by(email:, uid:)
if @user.persisted?
session[:user_id] = @user.id
redirect_to user_path
else
redirect_to root_path
end
end
def delete
session[:user_id] = nil
redirect_to top_path
end
end
ビューはこのように加筆
<!DOCTYPE html>
<html>
# ------省略-------
<body>
<main class="container mx-auto mt-28 px-5">
<div class="bg-indigo-200">
<% if user_signed_in? %>
<%= button_to "ログアウト", logout_path, class: "bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-full", method: :delete %>
<% else %>
<%= button_to "keycloak_ログイン", '/auth/keycloak', class: "bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-full", data: {turbo: false} %>
<% end %>
</div>
<%= yield %>
</main>
</body>
</html>
user_signed_in?などはヘルパーにしました。最後にサンプルをgithubにあげます。
設定が終わったら
$ rails s
でサーバーを立ち上げましょう。
keycloak_ログインボタンを押すとkeycloakのログイン画面へリダイレクトされます。
keycloakで作成したuserの名前とパスワードを入力するとログイン後のuserページに遷移できます。
結構簡単に実装ができましたので、皆様も是非お試しください。