是的,这是解决这个问题的合理方法。事实上,我认为StackOverflow 做同样的事情。不使用 OpenID 的人的自定义用户数据库也位于 openid.service.com,因此实际上在这种情况下他们也会使用 OpenID,尽管他们不知道。
需要注意的一件事是,您的示例中的 openid.service.com 将无法断言来自 Google 和其他人的原始声明标识符,因为辅助 RP 不会接受来自您的中介的声明,因为它对那些声明的 ID 没有权限. 相反,您可以做的是openid.service.com 和每个辅助 RP 之间的无身份验证OpenID。是的,OpenID 实际上有一个流程,其中没有声称的标识符从 OP 传递到 RP——只有扩展。因此,您可以使用 DotNetOpenAuthFetchRequest
和FetchResponse
扩展在辅助 RP 和中央服务之间请求用户的实际 claim_id。辅助RP必须非常小心只接受来自您的中央 RP 的断言。
这是辅助 RP 和中央 RP 之间的代码草图:
第 1 步:RP 向 openid.service.com 请求用户身份验证
OpenIdRelyingParty rp;
var request = rp.CreateRequest("https://openid.service.com/");
request.IsExtensionOnly = true;
var fetchRequest = new FetchRequest();
fetchRequest.Attributes.AddRequired("http://openid.service.com/useridentity");
request.AddExtension(fetchRequest);
request.RedirectToProvider();
第 2 步:openid.service.com,作为 OP,接收请求(作为一个 OP 是一个巨大的责任......这是一个非常不完整的示例。您应该参考可用的 OpenIdProvider 示例。)
OpenIdProvider op;
IRequest request = op.GetRequest();
/// ...
IAnonymousRequest anonRequest = request as IAnonymousRequest;
if (anonRequest != null) {
// The key part for this sample snippet is that you make sure the RP asking
// is one of your own, since you're not following the typical OpenID flow.
if (!IsWhiteListedRealm(hostRequest.Realm)) {
anonRequest.IsApproved = false; // reject all RPs that aren't in the whitelist
} else {
// Perhaps here is where you'll start your double role as an RP
// to authenticate the user if there isn't already a FormsAuth cookie.
}
}
return op.PrepareResponse(request).AsActionResult()
第 3 步:辅助 RP 接收来自您的代理 OpenID 服务的响应。
OpenIdRelyingParty rp;
var response = rp.GetResponse();
if (response != null) {
if (response.Provider.Uri.Authority != "openid.service.com") {
throw new Exception(); // only assertions from our own OP are trusted.
}
if (response.Status == AuthenticationStatus.ExtensionsOnly) {
var fetchResponse = response.GetExtension<FetchResponse>();
string claimedId = fetchResponse.GetAttributeValue("http://openid.service.com/useridentity");
FormsAuthentication.RedirectFromLoginPage(claimedId);
}
}
这些样本并不完整。并且上述内容不适用于担任这些角色的网站的许多正常实践安全缓解措施。这只是一个草图,概述了您的应用程序在特定情况下应采取的一些额外步骤。