14
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Digital Identity技術勉強会 #iddanceAdvent Calendar 2021

Day 7

IDサーバのOSS、ORY Kratosを試してみる

Last updated at Posted at 2021-12-06

Digital Identity技術勉強会 #iddance 7日目の記事です。

ID Stackを手掛けるORYの最新作、ORY Kratosを触ってみたので、どんな感じで使えそうか書いていきます。

なお、執筆時点でのバージョンは v0.8.0-alpha.3 です。

ORY Kratosとは

ユーザ管理と認証を実装しているヘッドレスなIDサーバのOSSです。

https://github.com/ory/kratos

実装されている主な機能としては以下です。

  • ログイン
  • ログアウト
  • ユーザ登録
  • プロフィール管理
  • アカウントリカバリー
  • Email検証
  • MFA

UIはご自分で、というものなので、最小構成としては以下のようになります。Your Appと書いた部分はサーバサイド・ブラウザ・ネイティブアプリケーションです。Cookieを共有するため、KratosとYour Appはトップレベルドメインは同じである必要があります。

image.png

前段にプロキシを挟んであげると、同じドメインできますし、 認証認可等、全く保護されていないAdmin APIを叩きたいときに ORY Oathkeeper のようなIAPを使えば、認可をつけることができます。

image.png

ログインやユーザ登録などFormの流れ

Kratosに送信するためのUIを自分で提供する都合上、Formを表示するための実装が結構面倒です。どのFormも大体同じ流れです。

  1. User AgentがYour Appにアクセス。
  2. Your AppはORY Kratosにリダイレクト。
  3. KratosはFlow IDをURLパラメータにつけてYour Appにリダイレクトで戻す。
  4. Your AppはFlow IDを使ってKratosのAPIを叩く。APIレスポンスを元にFormを組み立てる。メッセージやデフォルト値などもKratosのAPIレスポンス指示に書いてある。
  5. ユーザがフォームを入力し、Kratosに送信。
  6. 送信が成功したらリダイレクト。リダイレクト先は設定もしくは、Step 2のときにURLパラメータで指定された値。エラーがあれば、Step 2に戻る。

ここでは簡易的に書きましたが、公式ドキュメントではもっと詳しくシーケンス図で説明されています。

大まかな流れ自体はORY Hydraを使ったことある人であれば、ちょっと似ているので馴染みがあると思いますが、ここで面食らうのは「Kratosの支持通りにFormを組み立てる」ところです。

通常、ログインやユーザー登録などはフォームごとに実装することが多いと思いますが、Kratosの場合は、Kratosの指示(JSON)から自サービスのUIデザインのFormを組み立てるしくみを実装する必要があります。

実装サンプルはこちら。サンプルのpartialsディレクトリの中の実装を自サービスのデザインに合わせて実装するイメージです。ただ、このサンプルの通りに実装すると、ViewにKratosの複雑性を持ち込んでしまうことになるので、フロントエンド・サーバサイドで分業するなら、サーバサイドでKratosのUI指示を変換することを検討したほうがいいかもしれません。

各機能の特徴

ユーザ登録・プロフィール管理

ユーザ登録やプロフィール設定では、ユーザのスキーマを予め定義しておき、その定義に従ってユーザ登録・プロフィール変更のフォームの項目が生成されます。スキーマは1つだけでなく、複数定義することができます。例えばEmailとパスワードだけのスキーマを定義する場合は以下のようになります。

{
  "$id": "http://mydomain.com/schemas/v2/customer.schema.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "A customer (v2)",
  "type": "object",
  "properties": {
    "traits": {
      "type": "object",
      "properties": {
        "email": {
          "title": "E-Mail",
          "type": "string",
          "format": "email",

          // This tells Ory Kratos that the field should be used as the "username" for the username+password flow.
          // It is an extension to the regular JSON Schema vocabulary.
          "ory.sh/kratos": {
            "credentials": {
              "password": {
                "identifier": true
              }
            }
          }
        }
      }
    }
  }
}

注意が必要なのは、ここで定義したものはすべてユーザ自身が入力できてしまうことです。システム側で管理したいユーザに値を触られたくないプロパティは今のところ、Kratosに持たせることはできないので、それを実現するにはYour App側で管理することになります。

一応、issueは上がっていますが、実装優先順位的にすぐに実装されなさそうなので、早く欲しい場合はコントリビュートが必要です。

https://github.com/ory/kratos/issues/47

ログイン

KratosではPasswordを使ったログインとOpenID Connectを使用したソーシャルサインインに対応しています。OpenID Connectといえば、ORYにはOpenID Providerを実装したORY Hydraがありますが、Hydraとのシームレスな連携は未実装で、連携できるようにYour Appに実装する必要があります。

将来的に実装されるようですが、これも優先度が低く未実装です。とはいえ、この実装はそこまで面倒ではないので、自分で実装してまってもいいかなと思います。

https://github.com/ory/kratos/issues/273

MFA / 2FA

Kratosは TOTP、WebAuthn、Lookup Secretに対応しています。これらはKratosの設定で有効化できます。また、AAL(Authenticator Assurance Level)も対応されており、現状ではAAL1(パスワード or OIDCログイン)もしくはAAL2(パスワード or OIDCログイン + TOTP or WebAuthn or Lookup Secret)を要求できます。ログインのフロー開始時、Kratosにリダイレクトする際にパラメータで aal=aal2 のように指定することができ、その後、セッションを取得した際にもAALを確認することができます。

{
  ...
  "authenticator_assurance_level": "aal2",
  ...
}

https://www.ory.sh/kratos/docs/reference/api#operation/toSession

アカウントリカバリー

Emailを入力したら、リカバリーメールが飛び、メール内のリンクをクリックするとセッションが発行され、パスワードを設定できるページに飛びます。将来的にはEmail以外も対応しそうですが、今の時点ではEmailのみです。

https://www.ory.sh/kratos/docs/guides/account-recovery-password-reset

その他

組織アカウントとの相性が悪い

Kratosではユーザが編集できない情報を設定できないので、例えば組織IDを紐づけたり、組織の管理者がアカウントを作成して、Emailは変更されたくないなどの要件があったときは、Your Appで組織IDを持つようにしたり、Emailが更新されないように、KratosにForm送信が届く前にバリデーションをするなどの工夫が必要になります。

また、招待も一応できるものの、ユーザ体験としては微妙です。Admin APIを使ってユーザを作成し、アカウントリカバリーフローを使ってパスワードを設定させるというものですが、Admin APIを使ったユーザ作成時には Kratosがメールを送信してくれないので、自分で送信することになります。このメールをユーザがクリックしてもKratosとしてはEmail Verifiedにならないので、Kratosからどこかのタイミング(リカバリーフロー中もしくはパスワード設定後)もう一度、 メールが送信され、このメール中のリンクを踏むとEmail Verifiedになります。

https://www.ory.sh/kratos/docs/admin/managing-users-identities

以上を踏まえるとこんな感じの構成になります。Proxyから Kratosに直接プロキシされていたリクエストはYour Appを通って、必要に応じてバリデーションなどの追加処理を行います。

image.png

まとめ

ヘッドレスIDサーバのOSS、ORY Kratosの紹介をしました。

まだalphaバージョンで、足りない部分はたくさんありますが、それでも自分で一から実装するくらいなら、使ってもいいんじゃないかと思います。

14
5
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?