§Play 中的 OpenID 支持
OpenID 是一种协议,允许用户使用单个帐户访问多个服务。作为 Web 开发人员,您可以使用 OpenID 为用户提供一种使用他们已有的帐户登录的方法,例如他们的 Google 帐户。在企业中,您可能可以使用 OpenID 连接到公司的 SSO 服务器。
§OpenID 流程概述
- 用户向您提供他的 OpenID(一个 URL)。
- 您的服务器检查 URL 后面的内容以生成一个 URL,您需要将用户重定向到该 URL。
- 用户确认其 OpenID 提供商上的授权,并被重定向回您的服务器。
- 您的服务器从该重定向接收信息,并与提供商核实信息是否正确。
如果所有用户都使用相同的 OpenID 提供商(例如,如果您决定完全依赖 Google 帐户),则可以省略步骤 1。
§用法
要使用 OpenID,首先将 openId
添加到您的 build.sbt
文件中
libraryDependencies ++= Seq(
openId
)
现在,任何想要使用 OpenID 的控制器或组件都必须声明对 OpenIdClient 的依赖关系。
§Play 中的 OpenID
OpenID API 有两个重要的功能
OpenIdClient.redirectURL
计算应将用户重定向到的 URL。它涉及异步获取用户的 OpenID 页面,这就是它返回CompletionStage<String>
的原因。如果 OpenID 无效,则返回的CompletionStage
将以异常完成。OpenIdClient.verifiedId
检查当前请求以建立用户信息,包括其经过验证的 OpenID。它将异步调用 OpenID 服务器以检查信息的真实性,返回 UserInfo 的承诺。如果信息不正确或服务器检查失败(例如,如果重定向 URL 被伪造),则返回的CompletionStage
将以异常完成。
如果CompletionStage
失败,您可以定义一个回退,它将用户重定向回登录页面或返回BadRequest
。
§示例
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 保护的资源
在此文档中发现错误?此页面的源代码可以在 此处 找到。阅读完 文档指南 后,请随时贡献拉取请求。有疑问或建议要分享?转到 我们的社区论坛 与社区开始对话。