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