DotNetOpenAuth: Why I am not getting always the same OpenID given an e-mail?
Im trying to log in using OpenID/Relying Party (Google, Yahoo!..). My login page is as follows.
What I want to do is simple:
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.
The problem is that response.ClaimedIdentifier.OriginalString
that is what I THINK to be the OpenID is not unique. It's almost unique. Most of the time the value returned is the same, but sometimes, not always, for some reasons (specially changing browsers or computers), this value changes and I create another account for the user.
What am I doing wrong? What is the TRUE OpenID code that I must store that is unique regardless of browsers or computers?
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();
}
}
You're close, but slightly off in your code. The unique identifier is not response.ClaimedIdentifier.OriginalString
, but simply response.ClaimedIdentifier
. OriginalString is slightly different, and actually it probably should have been marked internal
to avoid confusion. Although ClaimedIdentifier
is of type Identifier
, it will actually automagically become a string when you assign it to a string variable, so don't worry about that.
Now about the splitting user accounts. Most likely what your problem is, is what OpenID calls "directed identity", which is where the OpenID Provider (Google in this case) sends a different OpenID for the same user, depending on what the value is for the IAuthenticationRequest.Realm
property. It's very important that your site make sure that the Realm
always has the same value so that Google recognizes your site as the same one every time, thus issuing to you the same ClaimedIdentifier
for the same user each time.
So what may be going wrong? If you're not setting the Realm
value explicitly, DotNetOpenAuth guesses that it is the URL of your home page. But that's based on the URL of the request that's coming in. For example, if users can visit your site using both http://www.yoursite.com/
and https://www.yoursite.com/
(note the https scheme on the second one) then both are legitimate home pages, and DotNetOpenAuth will use whichever scheme the user happens to be visiting your login page on. Similarly, if your site is available both at http://yoursite.com
and http://www.yoursite.com
(note the www) then that too becomes two different realm values. What you need to do then is set the realm explicitly, with something like:
relyingParty.CreateRequest(TextBoxOpenID.Text, "https://www.yoursite.com/").RedirectToProvider();
This will ensure that your users get the same ClaimedIdentifier each time.
精彩评论