DotNetOpenAuth: почему я не получаю всегда один и тот же OpenID при получении электронной почты? - PullRequest
4 голосов
/ 22 июня 2010

Я пытаюсь войти в систему, используя OpenID / Relying Party (Google, Yahoo! ..). Моя страница входа выглядит следующим образом.

То, что я хочу сделать, просто:

Получить OpenID от пользователя, сохранить его и связать с учетной записью пользователя. Каждый раз, когда этот уникальный OpenID возвращается от провайдера, я бы знал, что связанный пользователь теперь вошел в систему. Простой.

Проблема в том, что response.ClaimedIdentifier.OriginalString то, что я считаю OpenID, не является уникальным. Это почти уникально. В большинстве случаев возвращаемое значение совпадает, но иногда, не всегда, по некоторым причинам (особенно при смене браузеров или компьютеров), это значение изменяется, и я создаю для пользователя другую учетную запись.

Что я делаю не так? Какой ИСТИННЫЙ код 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();
                }
            }

1 Ответ

6 голосов
/ 25 июня 2010

Вы близки, но немного не в своем коде. Уникальный идентификатор не response.ClaimedIdentifier.OriginalString, а просто response.ClaimedIdentifier. OriginalString немного отличается, и на самом деле он, вероятно, должен быть помечен internal, чтобы избежать путаницы. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *) * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Active Only Сейчас, когда вы присваиваете ей строковую переменную, 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.com, так и http://www.yoursite.com (обратите внимание на www), то это тоже становится двумя различными значениями области. То, что вам нужно сделать, это установить область явно, что-то вроде:

relyingParty.CreateRequest(TextBoxOpenID.Text, "https://www.yoursite.com/").RedirectToProvider();

Это гарантирует, что ваши пользователи каждый раз получают один и тот же ClaimedIdentifier.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...