我正在尝试使用 OpenID/依赖方(Google、Yahoo!...)登录。我的登录页面如下。
我想做的很简单:
Get the OpenID from an user, store it, and associate it with an user account. Every time that unique OpenID is returned from the provider, I would know that the user associated is now logged in. Simple.
问题是 response.ClaimedIdentifier.OriginalString
我认为 OpenID 不是唯一的。它几乎是独一无二的。大多数情况下,返回的值是相同的,但有时,并非总是如此,由于某些原因(特别是更改浏览器或计算机),此值会发生变化,我会为用户创建另一个帐户。
我做错了什么?无论浏览器或计算机如何,我必须存储唯一的 TRUE OpenID 代码是什么?
public partial class Pages_User_LoginOpenID : LivrePage
{
OpenIdRelyingParty relyingParty = new OpenIdRelyingParty();
IAuthenticationResponse response = null;
protected void Page_Load(object sender, EventArgs e)
{
response = relyingParty.GetResponse();
if (response != null)
{
switch (response.Status)
{
case AuthenticationStatus.Authenticated:
// verifico se existe um usuário com este openid
OpenId openId = UserHelper.GetSession().CreateCriteria<OpenId>().Add(Expression.Eq("IdentifierString", response.ClaimedIdentifier.OriginalString)).UniqueResult<OpenId>();
if (openId == null)
{
openId = new OpenId();
openId.IdentifierString = response.ClaimedIdentifier.OriginalString;
// não existe usuário com este OpenId
User newUser = UserHelper.CreateUser(openId);
SecurityManager.Login(newUser.Id);
}
else
SecurityManager.Login(openId.User.Id);
Response.Redirect(UrlFactory.GetUrlForPage(UrlFactory.PageName.Home));
break;
default:
break;
}
}
}
// processes the login button click
protected void ButtonLogin_Click(object sender, EventArgs e)
{
if (response == null)
relyingParty.CreateRequest(TextBoxOpenID.Text).RedirectToProvider();
}
}
最佳答案
您很接近,但您的代码略有偏差。唯一标识符不是 response.ClaimedIdentifier.OriginalString
,而只是 response.ClaimedIdentifier
。 OriginalString 略有不同,实际上它可能应该标记为 internal
以避免混淆。虽然 ClaimedIdentifier
是 Identifier
类型,但当您将它分配给字符串变量时,它实际上会自动变成一个字符串,所以不用担心。
现在关于拆分用户帐户。您的问题很可能是 OpenID 所谓的“定向身份”,即 OpenID 提供商(在本例中为 Google)根据值是什么为同一用户发送不同 OpenID对于 IAuthenticationRequest.Realm
属性。您的站点确保 Realm
始终具有相同的值非常重要,这样 Google 每次都会将您的站点识别为相同的站点,从而向您发出相同的 ClaimedIdentifier
每次都针对同一用户。
那么可能出了什么问题?如果您没有显式设置 Realm
值,DotNetOpenAuth 会猜测它是您主页的 URL。但这是基于传入请求的 URL。例如,如果用户可以使用 both http://www.yoursite.com/
和 https://www.yoursite.com/
(注意第二个上的 https 方案)那么两者都是合法的主页,并且 DotNetOpenAuth 将使用用户碰巧访问您的登录页面的任何方案。类似地,如果您的网站在 http://yoursite.com
和 http://www.yoursite.com
(注意 www)上都可用,那么它也变成了两个不同的境界值。然后您需要做的是明确设置领域,例如:
relyingParty.CreateRequest(TextBoxOpenID.Text, "https://www.yoursite.com/").RedirectToProvider();
这将确保您的用户每次都获得相同的 ClaimedIdentifier。
关于c# - DotNetOpenAuth:为什么我在给定电子邮件时不总是获得相同的 OpenID?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3089727/