Как использовать DotNetOpenAuth с Google Apps для доменов в качестве поставщика - PullRequest
1 голос
/ 04 августа 2011

Я использую DotNetOpenAuth v3.5.0.10357 для поддержки OpenID.Сайт был создан с использованием шаблона DNOA VS 2010 MVC, и я немного изменил его (не используя поддержку Ajax или пользовательские элементы управления - вместо этого используйте плагин OpenID jquery).Я использую конкретную версию, потому что я также реализовал поддержку Facebook.Это все работает нормально.Но когда я пытаюсь использовать приложения Google, кажется, что он работает не так, как я ожидал.Вот что происходит:

1) Я отправляю свою форму, используя следующий провайдер открытого идентификатора: https://www.google.com/accounts/o8/site-xrds?ns=2&hd=example.com (я получил это путем проверки файла, возвращенного https://www.google.com/accounts/o8/.well-known/host-meta?hd=example.com)

2) Iя перенаправлен в приложения Google и прошу войти с моими учетными данными приложений Google.

3) Я перенаправлен на: http://example.com/Auth/LogOnPostAssertion?dnoa.uipopup=1&dnoa.popupUISupported=1&index=0&dnoa.userSuppliedIdentifier=https://www.google.com/accounts/o8/site-xrds?ns=2&hd=example.com&dnoa.op_endpoint=https://www.google.com/a/example.com/o8/ud?be=o8&dnoa.claimed_id=&openid.ns=http://specs.openid.net/auth/2.0&openid.mode=id_res&openid.op_endpoint=https://www.google.com/a/example.com/o8/ud?be=o8&openid.response_nonce=2011-08-04T05:03:14ZmDjx966VdNKGAQ&openid.return_to=http://example.com/Auth/LogOnPostAssertion?dnoa.uipopup=1&dnoa.popupUISupported=1&index=0&dnoa.userSuppliedIdentifier=https%3A%2F%2Fwww.google.com%2Faccounts%2Fo8%2Fsite-xrds%3Fns%3D2%26hd%3Dexample.com&dnoa.op_endpoint=https%3A%2F%2Fwww.google.com%2Fa%2Fexample.com%2Fo8%2Fud%3Fbe%3Do8&dnoa.claimed_id=&openid.assoc_handle=redacted_value&openid.signed=op_endpoint,claimed_id,identity,return_to,response_nonce,assoc_handle,ns.ext1,ext1.mode,ext1.type.alias3,ext1.value.alias3,ext1.type.alias1,ext1.value.alias1&openid.sig=redacted_value=&openid.identity=http://example.com/openid?id=redacted_value&openid.claimed_id=http://example.com/openid?id=redacted_value&openid.ns.ext1=http://openid.net/srv/ax/1.0&openid.ext1.mode=fetch_response&openid.ext1.type.alias3=http://schema.openid.net/contact/email&openid.ext1.value.alias3=mark.miller@example.com&openid.ext1.type.alias1=http://axschema.org/contact/email&openid.ext1.value.alias1=mark.miller@example.com&openid.ns.ext2=http://specs.openid.net/extensions/ui/1.0&openid.ext2.mode=popup

Затем, когда вызывается RelyingParty.GetResponse(), я перенаправлен на http://example.com/openid. Я знаю, что если я размещаю свой собственный XRD, мне нужно будет предоставить ответ, но, похоже, все, что нужно, есть в ответе.Разве он не должен просто прочитать значения из запроса, использовать заявленный идентификатор в строке запроса и покончить с этим?Действие контроллера ниже - свойство RelyingParty имеет тип IOpenIDRelyingParty и включает в себя экземпляр типа OpenIdRelyingParty из библиотеки DotNetOpenAuth.

Должен ли я обрабатывать этот случай по-другому?Или этот сценарий не полностью поддерживается?Если это не поддерживается, есть ли у кого-нибудь направление, где я мог бы добавить поддержку самостоятельно?

public ActionResult LogOnPostAssertion(string openid_openidAuthData, string returnUrl){
var response = this.RelyingParty.GetResponse();
if (response == null)
{
    //Let us submit the request to OpenID provider
    Identifier id;
    if (Identifier.TryParse(openid_openidAuthData, out id))
    {
        try
        {
            var request = this.RelyingParty.CreateRequest(id, Realm.AutoDetect, Url.ActionFull("LogOnPostAssertion"), this.PrivacyPolicyUrl);
            return request.RedirectingResponse.AsActionResult();
        }
        catch (ProtocolException ex)
        {
            ViewBag.Message = ex.Message;
        }
    }
    else
    {
        ViewBag.Message = "Invalid identifier";
    }
} 

if (response != null && String.IsNullOrEmpty(ViewBag.Message))
{
    switch (response.Status)
    {
        case AuthenticationStatus.Authenticated:
            var token = RelyingPartyLogic.User.ProcessUserLogin(response);
            this.FormsAuth.SignIn(token.ClaimedIdentifier, false);
            if (!String.IsNullOrEmpty(returnUrl))
            {
                return Redirect(returnUrl);
            }
            else
            {
                return RedirectToAction("Index", "Home");
            }
        case AuthenticationStatus.Canceled:
            ModelState.AddModelError("OpenID", "It looks like you canceled login at your OpenID Provider.");
            break;
        case AuthenticationStatus.Failed:
            ModelState.AddModelError("OpenID", response.Exception.Message);
            break;
    }
}

// If we're to this point, login didn't complete successfully.
// Show the LogOn view again to show the user any errors and
// give another chance to complete login.
return View("LogOn");

}

EDIT Хорошо, так что после отладки того же процесса, используямоя стандартная учетная запись gmail (например, @ gmail.com, а не домен приложений Google, @ example.com), я получаю ответ от Google , почти , идентичный приведенному выше (# 3).Все в значительной степени одинаково, за исключением идентификаторов и вещей, связанных с параметром dnoa.userSuppliedIdentifier - что и ожидается.Но одна вещь, которая не совпадает, это параметр openid.claimedid.Вот как они выглядят:

openid.claimed_id=http://example.com/openid?id=long_integer_value

openid.claimed_id=https://www.google.com/accounts/o8/id?id=some_hash_value

Таким образом, похоже, что DNOA должен выполнить вторичную проверку OP (поставщик OpenID) с использованиемзначение требуемого_ид.Я предполагаю, что мне нужно предоставить конечную точку, которая отвечает на этот URL.Тем не менее, мой вопрос становится таким, поскольку я заранее не знаю значения «id», как мне ответить на запрос от DNOA?

1 Ответ

2 голосов
/ 05 августа 2011

Хорошо, я нашел решение здесь

Я создал новое Действие GoogleAppsLogOn, которое совпадает с действием в моем исходном вопросе, и добавил следующие две строки кода вверху:

this.RelyingParty.DiscoveryServices.Clear();
this.RelyingParty.DiscoveryServices.Add(new HostMetaDiscoveryService() { UseGoogleHostedHostMeta = true });

Прямо перед звонком на RelyingParty.GetResponse(). Если вы используете шаблоны VS и проверяющая сторона - IOpenIdRelyingParty, вы можете просто добавить DiscoveryService s к интерфейсу и классу оболочки, предоставленному в проекте RelyingPartyLogic, который также является частью шаблонов.

...