Railsで OpenID Connect(OIDC) に準拠したクライアント実装
RailsでOpenID Connect(OIDC) に準拠したクライアント実装の備忘録です。
OpenID Connect
OpenID Connect(OIDC)は、ユーザーの同意に基づいてサービス間で ID 情報をやり取りするための標準仕様です。OAuth 2.0 プロトコルを使用して構築されたオープン・スタンダードです。
【情シス基礎知識】OpenID Connectとは? 第一回 認証基盤のこれからを支えるOpenID Connect | オブジェクトの広場使用ライブラリ
OpenID Foundation の、各言語の関連ライブラリ一覧 でRubyのライブラリが紹介されています。
Certified Relying Party Libraries
> Ruby
にて
OpenID Foundation
- RP sample implementation in Ruby on Rails using ‘openid_connect’ gem
- Target Environment: Ruby for any Rack-based applications (including Ruby on Rails)
- License: MIT
- Certified By: Nov Matake
- Conformance Profiles: Basic RP
使用方法
シンプルなサンプル
https://github.com/nov/openid_connect_sample2/blob/master/sample_rp.rb より
require 'openid_connect'
OpenIDConnect.debug!
client = OpenIDConnect::Client.new(
identifier: 'rp.dev',
secret: '42347d901a6686a533067285ed13ee1b475121a6ece10446299f4be62e4e4bfc',
redirect_uri: 'http://rp.dev/providers/3/open_id',
host: 'op2.dev',
scheme: 'http',
authorization_endpoint: '/authorizations/new',
token_endpoint: '/tokens',
userinfo_endpoint: '/user_info'
)
redirect_uri = client.authorization_uri(
scope: [:email, :profile],
state: SecureRandom.hex(8),
nonce: SecureRandom.hex(8)
)
puts redirect_uri
`open "#{redirect_uri}"`
print 'code: ' and STDOUT.flush
code = gets.chop
client.authorization_code = code
client.access_token!
サンプル(Controller)
コントローラでアクセストークンを受け取り表示するまでのサンプルです。
class OpenConnectController
def login
render inline: "[<a href='<%= open_connect_auth_url %>'>OpenID連携</a>]"
end
def auth
client = init_client
params = {
scope: [:openid, :user_info],
state: SecureRandom.hex(8),
nonce: SecureRandom.hex(16)
}
redirect_uri = client.authorization_uri(params)
session[:open_connect_auth] = params
redirect_to redirect_uri, status: 302
end
def authorize
code = params[:code]
state = params[:state]
render plain: 'ERROR: state mismatch' and return unless session[:open_connect_auth]['state'] == state
client = init_client
client.authorization_code = code
access_token = client.access_token!
p access_token
p access_token.id_token
render json: {
success: true,
id_token: access_token.id_token
}
end
private
def init_client
@client ||= OpenIDConnect::Client.new(
identifier: 'rp.dev',
secret: '42347d901a6686a533067285ed13ee1b475121a6ece10446299f4be62e4e4bfc',
redirect_uri: 'https://xxxxxxxx.xxx/open_connect/authorize',
host: 'op2.dev',
scheme: 'https',
authorization_endpoint: '/oauth2/auth',
token_endpoint: '/oauth2/token'
)
end
end