我正在创建一个.NET网站,它将为其用户提供特定的服务。让我们称之为service1.com。将来会有service2.com,他们将共享数据库。我还希望通过提供Google,Facebook,Twitter +自定义注册登录来进行用户友好的身份验证,以防用户没有Google等,以便他们注册。我将使用DotNetOpenAuth库。所以场景与SO类似。
现在Google存在问题:它提供different claimed identifier for different realm - 这意味着我无法将其用作用户ID,但必须在图片中添加电子邮件以解析用户(like SO is doing)
除此之外,这意味着我必须支持Facebook Connect,Twitter以及每个服务站点上的所有其他登录选项。
所以我想出了OpenID代理的想法:
所以最终结果看起来像这样:
优点:
CONS:
这是实现这样一个系统的一个不错的方法,还有其他缺点吗?
答案 0 :(得分:2)
是的,这是解决此问题的合理方法。事实上,我认为 StackOverflow做同样的事情。不使用OpenID的人的自定义用户数据库也位于openid.service.com,所以实际上他们也会在这种情况下使用OpenID,尽管他们不知道。
需要注意的一点是,在您的示例中,openid.service.com将不能够从Google和其他人声明原始的声明标识符,因为辅助RP将不接受您的断言中介,因为它对那些声称的ID没有权限。相反,您可以在openid.service.com和每个辅助RP之间执行无身份验证 OpenID。是的,OpenID实际上有一个流程,其中没有声明的标识符从OP传递到RP - 仅扩展。因此,您可以使用DotNetOpenAuth FetchRequest
和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 samples that are available。 )
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);
}
}
这些样本不完整。并且上述内容不适用于填充这些角色的网站的许多常规安全缓解措施。这只是一个草图,概述了您的应用程序在您的特定情况下应采取的一些额外步骤。