文件

§Play 中的 OpenID 支援

OpenID 是一種讓使用者使用單一帳戶存取多項服務的通訊協定。身為網路開發人員,您可以使用 OpenID 為使用者提供一種使用他們既有帳戶(例如他們的 Google 帳戶)登入的方式。在企業中,您或許可以使用 OpenID 連線到公司的 SSO 伺服器。

§OpenID 流程簡述

  1. 使用者提供他的 OpenID(一個 URL)給您。
  2. 您的伺服器會檢查 URL 後面的內容,以產生您需要將使用者重新導向的 URL。
  3. 使用者在其 OpenID 提供者上確認授權,並重新導向回您的伺服器。
  4. 您的伺服器從該重新導向接收資訊,並與提供者檢查資訊是否正確。

如果您的所有使用者都使用相同的 OpenID 提供者(例如,如果您決定完全依賴 Google 帳戶),則可以省略步驟 1。

§用法

若要使用 OpenID,請先將 openId 新增至您的 build.sbt 檔案

libraryDependencies ++= Seq(
  openId
)

現在,任何想要使用 OpenID 的控制器或元件都必須宣告對 OpenIdClient 的依賴關係。

§OpenID 在 Play 中

OpenID API 有兩個重要的功能

§範例

conf/routes:

GET     /openID/login               controllers.OpenIDController.login()
POST    /openID/login               controllers.OpenIDController.loginPost(request: Request)
GET     /openID/callback            controllers.OpenIDController.openIDCallback(request: Request)

控制器

package controllers;

import java.util.*;
import java.util.concurrent.CompletionStage;
import javax.inject.Inject;
import play.data.*;
import play.libs.openid.*;
import play.mvc.*;
import play.twirl.api.Html;

public class OpenIDController extends Controller {

  @Inject OpenIdClient openIdClient;

  @Inject FormFactory formFactory;

  public Result login() {
    return ok(views.html.login.render(""));
  }

  public CompletionStage<Result> loginPost(Http.Request request) {

    // Form data
    DynamicForm requestData = formFactory.form().bindFromRequest(request);
    String openID = requestData.get("openID");

    CompletionStage<String> redirectUrlPromise =
        openIdClient.redirectURL(
            openID, routes.OpenIDController.openIDCallback().absoluteURL(request));

    return redirectUrlPromise
        .thenApply(Controller::redirect)
        .exceptionally(throwable -> badRequest(views.html.login.render(throwable.getMessage())));
  }

  public CompletionStage<Result> openIDCallback(Http.Request request) {

    CompletionStage<UserInfo> userInfoPromise = openIdClient.verifiedId(request);

    CompletionStage<Result> resultPromise =
        userInfoPromise
            .thenApply(userInfo -> ok(userInfo.id() + "\n" + userInfo.attributes()))
            .exceptionally(
                throwable -> badRequest(views.html.login.render(throwable.getMessage())));

    return resultPromise;
  }

  public static class views {
    public static class html {
      public static class login {
        public static Html render(String msg) {
          return javaguide.ws.html.login.render(msg);
        }
      }
    }
  }
}

§延伸屬性

使用者的 OpenID 可提供其身分。此協定也支援取得延伸屬性,例如電子郵件地址、名字或姓氏。

您可以向 OpenID 伺服器要求選用屬性及/或必要屬性。要求必要屬性表示如果使用者未提供這些屬性,則無法登入您的服務。

延伸屬性會在重新導向 URL 中要求

Map<String, String> attributes = new HashMap<>();
attributes.put("email", "http://schema.openid.net/contact/email");

CompletionStage<String> redirectUrlPromise =
    openIdClient.redirectURL(
        openID, routes.OpenIDController.openIDCallback().absoluteURL(request), attributes);

屬性接著會在 OpenID 伺服器提供的 UserInfo 中提供。

下一步:存取受 OAuth 保護的資源


在此文件發現錯誤?此頁面的原始程式碼可在此處找到here。在閱讀文件準則後,請隨時貢獻一個 pull 要求。有問題或建議要分享?前往我們的社群論壇與社群展開對話。