DotNetOpenAuth:为什么我没有得到一封电子邮件相同的OpenID?

And*_*ena 4 .net c# dotnetopenauth

我试图使用OpenID /依赖方(Google,Yahoo!..)登录.我的登录页面如下.

我想做的很简单:

从用户获取OpenID,存储它,并将其与用户帐户相关联.每次从提供程序返回唯一的OpenID时,我都会知道关联的用户现在已登录.简单.

问题是,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();
                }
            }
Run Code Online (Sandbox Code Playgroud)

And*_*ott 6

你很近,但在你的代码中略有偏差.唯一标识符不是response.ClaimedIdentifier.OriginalString,而是简单response.ClaimedIdentifier.OriginalString略有不同,实际上它应该被标记internal以避免混淆.虽然ClaimedIdentifier是类型Identifier,但是当你将它分配给字符串变量时,它实际上会自动变成一个字符串,所以不要担心.

现在关于拆分用户帐户.最有可能的问题是,OpenID称之为"定向身份",这是OpenID提供商(在本例中为Google)为同一用户发送不同 OpenID的地方,具体取决于该IAuthenticationRequest.Realm属性的值.非常重要的是,您的网站必须确保Realm始终具有相同的值,以便Google每次都将您的网站识别为同一个网站,从而每次ClaimedIdentifier向同一用户发送相同的网站.

那可能会出现什么问题?如果您没有Realm明确设置值,DotNetOpenAuth会猜测它是您主页的URL.但是,这是基于该公司在未来的请求的URL.例如,如果用户可以通过访问您的网站 http://www.yoursite.com/https://www.yoursite.com/(注意第二个https方案),则都是合法的主页,并DotNetOpenAuth将使用任何方案的用户碰巧正在访问您的登录页面.同样,如果您的网站在http://yoursite.comhttp://www.yoursite.com(注意www)都可用,那么它也会成为两个不同的领域值.你需要做的是明确地设置领域,例如:

relyingParty.CreateRequest(TextBoxOpenID.Text, "https://www.yoursite.com/").RedirectToProvider();
Run Code Online (Sandbox Code Playgroud)

这将确保您的用户每次都获得相同的ClaimedIdentifier.