OpenID Provider (OP; IdP) ごとの設定例

Google Identity Platform

google に接続する方法.

issuer"https://accounts.google.com".

discovery: true の場合

client secret は, 環境変数で与えるのが基本。

Ruby
[RAW]
  1. Rails.application.configure do |config|
  2. config.middleware.use OmniAuth::Builder do
  3. # google: OpenID Connect
  4. provider :openid_connect, {
  5. name: :google_oauth2,
  6. issuer: 'https://accounts.google.com',
  7. # 'openid' で OpenID Connect
  8. # サポート範囲は <issuer>/.well-known/openid-configuration
  9. scope: [:openid, :email, :profile],
  10. # 'code' is Basic flow. 'token id_token' is Implicit flow.
  11. response_type: :code,
  12. discovery: true,
  13. client_options: {
  14. scheme: "https",
  15. host: "accounts.google.com",
  16. port: 443, # 省略不可.
  17. # Google API Console での指定と厳密に一致していること.
  18. # https://console.cloud.google.com/apis/credentials
  19. identifier: ENV['GOOGLE_CLIENT_ID'],
  20. secret: ENV['GOOGLE_CLIENT_SECRET'],
  21. redirect_uri: ENV['GOOGLE_REDIRECT_URI'],
  22. },
  23. }

discovery: falseの場合

authorization_endpoint などを指定してやる必要がある。内容は, <issuer>/.well-known/openid-configuration で得られるものと同じ。

それから, id_token を検証するために, 認証サーバの公開鍵をロードしておく必要がある。クライアントの鍵ではない。

Ruby
[RAW]
  1. provider :openid_connect, {
  2. name: :google_oauth2,
  3. issuer: 'https://accounts.google.com',
  4. scope: [:openid, :email, :profile],
  5. response_type: :code,
  6. discovery: false,
  7. client_options: {
  8. scheme: "https",
  9. host: "accounts.google.com",
  10. port: 443, # 省略不可.
  11. # Google API Console での指定と厳密に一致していること.
  12. # https://console.cloud.google.com/apis/credentials
  13. identifier: ENV['GOOGLE_CLIENT_ID'],
  14. secret: ENV['GOOGLE_CLIENT_SECRET'],
  15. redirect_uri: ENV['GOOGLE_REDIRECT_URI'],
  16. # discovery: falseの時に指定.
  17. authorization_endpoint: '/o/oauth2/v2/auth',
  18. token_endpoint: 'https://oauth2.googleapis.com/token',
  19. userinfo_endpoint: 'https://openidconnect.googleapis.com/v1/userinfo',
  20. },
  21. #client_signing_alg: 'RS256',
  22. client_x509_signing_key: JSON.load(File.read(Rails.root.to_s + '/certs'))
  23. }

certsファイルは, 形式がいくつかある。

PEM ファイルや, 複数の PEM を JSON で束ねたもの (以下に示す.) の場合は, client_x509_signing_key オプションに与える。

どの公開鍵が使われるかは分からないので、全部読み込んでおくこと。

JavaScript
[RAW]
  1. {
  2. "960a7e8e8341ed752f12b186fa129731fe0b04c0": "-----BEGIN CERTIFICATE-----\nMIIDJjCCAg6gAwIBAgIICKXnIDCzjxQwDQYJKoZIhvcNAQEFBQAwNjE0MDIGA1UE\nAxMrZmVkZXJhdGVkLXNp
  3. ...

JSON Web Key (JWK) フォーマットまたは JWK Set フォーマットの場合は, client_jwk_signing_key オプションに与える.

JavaScript
[RAW]
  1. {
  2. "keys": [
  3. {
  4. "n": "xHKHysGHfZby92stAyC4Xkp7t2Ib6TEha1G11UwGgmrv7pgpjKBJkO1XtvvT2L3pEylhcKhLgO8fx5R-rKceezZ_YpTyuT1vHHsWYJxeocV5m0V70_Nvgfysl6lS_gdvfT68dMNk1EL8bIk9uiCMIotVpcq4FIeID75Dendq_oTuXOZVeCi1r8q0qeMWN7nFZEJCnxzayNOTE7-eC8FRMRiu-e3tOtkruga3Cz62nkkrGtQyAaQtUntrDTQxjE2TNhBvWBWDVOfvG-uCe2JkhfDC7CZlE6tpBo-VkyIGGZjR5qBlYTKx6ZJjWeQC13lpwd7WB1vKtBSKGH2vKuBbrQ",
  5. "kty": "RSA",
  6. "kid": "c1771814ba6a70693fb9412da3c6e90c2bf5b927",
  7. "e": "AQAB",
  8. "alg": "RS256",
  9. "use": "sig"
  10. },
  11. { ...

RSA 暗号の公開鍵を構成する, modulus n (法) と encryption or public exponent e (公開指数) が含まれる。

Yahoo! ID連携 v2

Yahoo! JAPAN.

discovery オプションは必ず true.

issuer"https://auth.login.yahoo.co.jp/yconnect/v2". ファイルpath部分がある.

Ruby
[RAW]
  1. provider :openid_connect, {
  2. name: :yahoojapan,
  3. issuer: 'https://auth.login.yahoo.co.jp/yconnect/v2',
  4. scope: [:openid, :email, :profile, :address],
  5. response_type: :code,
  6. discovery: true,
  7. client_options: {
  8. scheme: "https",
  9. host: "auth.login.yahoo.co.jp",
  10. port: 443, # 省略不可.
  11. identifier: ENV['YAHOOJP_CLIENT_ID'],
  12. secret: ENV['YAHOOJP_CLIENT_SECRET'],
  13. redirect_uri: ENV['YAHOOJP_REDIRECT_URI'],
  14. },
  15. }

Microsoft Azure Active Directory v2

Azure AD v2は、ほかの IdP と挙動が近くなった。end_session_endpoint をサポートしており、Single Logout (SLO) が可能.

issuer"https://login.microsoftonline.com/{tenantid}/v2.0" の形. {tenantid} 部分にテナントIDが入る。

send_client_secret_to_token_endpoint オプションを true にすること。omniauth-openid-connect 内で workaround が動く. 指定しなくても動くようにしました。

discovery オプションは必ず true.

Ruby
[RAW]
  1. provider :openid_connect, {
  2. name: :azure_ad,
  3. issuer: ENV['AZURE_ISSUER'],
  4. scope: [:openid],
  5. # ドキュメントでは, Azure ADは, 'id_token' を含めなければならないことになっている;
  6. # https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-openid-connect-code
  7. # 実際には, ['code', 'id_token'] はレスポンスが不正. フラグメントになる.
  8. # ['code', 'id_token', 'token'] では unsupported_response_type
  9. # => 結局, 'code' のみでよい.
  10. response_type: ['code'],
  11. # Azure ADのみ.
  12. send_client_secret_to_token_endpoint: true,
  13. discovery: true,
  14. client_options: {
  15. scheme: "https",
  16. host: "login.windows.net", # issuer のホストと違う!
  17. port: 443, # 省略不可.
  18. identifier: ENV['AZURE_CLIENT_ID'],
  19. secret: ENV['AZURE_CLIENT_SECRET'],
  20. redirect_uri: ENV['AZURE_REDIRECT_URI'],
  21. },
  22. }

nov/openid_connect_sample

Ruby
[RAW]
  1. # -*- coding:utf-8; mode:ruby -*-
  2. # omniauth を使う.
  3. # See https://github.com/omniauth/omniauth
  4. Rails.application.configure do |config|
  5. config.middleware.use OmniAuth::Builder do
  6. if !Rails.env.production?
  7. provider :developer
  8. provider :openid_connect, {
  9. # /auth/<name> が認証開始のURLになる.
  10. name: :nov_op_sample,
  11. # これがないと, エラー
  12. # 末尾の '/' は付けてはいけない.
  13. # <issuer>/.well-known/openid-configuration
  14. issuer: 'http://localhost:4000',
  15. # 'openid' で OpenID Connect
  16. scope: ["openid","profile","email","address","phone"],
  17. # 'code' is Basic flow. 'token id_token' is Implicit flow.
  18. response_type: :code,
  19. # 有効にしないと, public_key() 内で config.jwks が使われない.
  20. # 必ず true にすること。(デフォルトはfalse)
  21. discovery: true,
  22. # rack-oauth2 パッケージ, Rack::OAuth2::Client.new() に渡される.
  23. # 初期値は, omniauth-openid-connect パッケージ内,
  24. # omniauth/strategies/openid_connect.rb
  25. client_options: {
  26. # omniauth-openid-connect パッケージ内,
  27. # omniauth/strategies/openid_connect.rb:issuer() 内で,
  28. # 上の issuer オプションは使わず, 次の3要素から issuer を作っている.
  29. scheme: "http",
  30. host: "localhost",
  31. port: 4000, # 80番でも省略できない.
  32. # OP側と厳密に合わせる
  33. identifier: クライアントID,
  34. secret: クライアントsecret,
  35. redirect_uri: "http://localhost:3000/auth/nov_op_sample/callback",
  36. },
  37. }
  38. end # !Rails.env.production?
  39. end
  40. end
  41. # See http://qiita.com/nekogeruge_987/items/8bd307f9ae31f27c248a
  42. # http://stackoverflow.com/questions/10963286/callback-denied-with-omniauth
  43. OmniAuth.config.on_failure = Proc.new do |env|
  44. OmniAuth::FailureEndpoint.new(env).redirect_to_failure
  45. end