§Play の OpenID サポート
OpenID はユーザが単一のアカウントで複数のサービスにアクセスできるようにするためのプロトコルです。 Web 開発者としては、 OpenID を使うことで、ユーザが別のサービスで既に作成してあるアカウント (例えば Google アカウント) であなたの Web アプリケーションにログインできるようになります。エンタープライズ向けには、企業の SSO サーバに接続するために OpenID を使うといったことも考えられます。
§OpenID のフロー概要
- ユーザが OpenID (ある URL) を提供します。
- アプリケーションサーバが URL の示すコンテンツを検証し、ユーザのリダイレクト先 URL を生成します。
- ユーザが OpenID プロバイダのサイトにて認可情報を確認し、アプリケーションサーバに再度リダイレクトされます。
- アプリケーションサーバがリダイレクトから認可情報を取得して、その情報が正しいことをプロバイダに確認します。
すべてのユーザが同じ OpenID プロバイダを使う場合 (例えば Google アカウントにのみ依存すると決断した場合) 、ステップ 1 を省略することができます。
§Play における OpenID
OpenID API には特に重要な関数が二つあります。
OpenID.redirectURL
は、ユーザのリダイレクト先 URL を計算する関数です。この関数は、非同期でユーザの OpenID ページを検索するため、Future[String]
を返します。OpenID が無効な場合、返却されるFuture
は失敗します。OpenID.verifiedId
は、暗黙的なRequest
を引数にとり、それを元に検証済みの OpenID を始めとするユーザの認可情報を組み立てます。この関数は、非同期に認可元の情報を確認するため、 OpenID サーバと通信を行います。このため、Future[UserInfo]
が返却されます。認可情報が不正か、サーバが単に (リダイレクト URL が書き換えられるなどの理由で) 確認に失敗した場合、返却されるFuture
は失敗します。
Future
が失敗するかもしれないので、ユーザーをログインページにリダイレクトするか、または BadRequest
を返すフォールバックを定義することができます。
次に、とあるコントローラから抽出した例を示します。
def login = Action {
Ok(views.html.login())
}
def loginPost = Action { implicit request =>
Form(single(
"openid" -> nonEmptyText
)).bindFromRequest.fold(
error => {
Logger.info("bad request " + error.toString)
BadRequest(error.toString)
},
{
case (openid) => AsyncResult(OpenID.redirectURL(openid, routes.Application.openIDCallback.absoluteURL())
.map( url => Redirect(url))
.recover { case Thrown(error) => Redirect(routes.Application.login) }
)
}
)
}
def openIDCallback = Action { implicit request =>
AsyncResult(
OpenID.verifiedId.map(info => Ok(info.id + "\n" + info.attributes))
.recover { case Thrown(t) =>
// Here you should look at the error, and give feedback to the user
Redirect(routes.Application.login)
}
)
}
§拡張属性
OpenID はユーザの同一性を確かめるために利用することができます。それ以外にメールアドレスや名前、苗字などの取得のために 拡張属性 というものもサポートされています。
OpenID サーバに対しては、*任意* および 必須 の属性のどちらか一方または両方をリクエストすることができます。必須の属性を要求するということは、ユーザがその情報を提供しないかぎり、あなたのサービスへログインできないことを意味します。
拡張属性はリダイレクト URL の中でリクエストされます。
OpenID.redirectURL(
openid,
routes.Application.openIDCallback.absoluteURL(),
Seq("email" -> "http://schema.openid.net/contact/email")
)
リクエストした属性は OpenID サーバから返却された UserInfo
より取得することができます。
次ページ: OAuth
このドキュメントの翻訳は Play チームによってメンテナンスされているものではありません。 間違いを見つけた場合、このページのソースコードを ここ で確認することができます。 ドキュメントガイドライン を読んで、お気軽にプルリクエストを送ってください。