DotNetOpenAuth - “视图”如何与此互动

时间:2010-11-29 06:00:49

标签: asp.net-mvc refactoring openid dotnetopenauth

我一直在寻找重构我的登录控制器以获得更好的代码可读性。在这样做的过程中,我遇到了Programmatic OpenID Relying Party example看起来像这样的

using DotNetOpenAuth.Messaging;

public ActionResult LogOn()
{
    var openid = new OpenIdRelyingParty();
    IAuthenticationResponse response = openid.GetResponse();

    if (response != null)
    {
        switch (response.Status)
        {
            case AuthenticationStatus.Authenticated:
                FormsAuthentication.RedirectFromLoginPage(
                    response.ClaimedIdentifier, false);
                break;
            case AuthenticationStatus.Canceled:
                ModelState.AddModelError("loginIdentifier",
                    "Login was cancelled at the provider");
                break;
            case AuthenticationStatus.Failed:
                ModelState.AddModelError("loginIdentifier",
                    "Login failed using the provided OpenID identifier");
                break;
        }
    }           

    return View();
}

[System.Web.Mvc.AcceptVerbs(HttpVerbs.Post)]
public ActionResult LogOn(string loginIdentifier)
{
    if (!Identifier.IsValid(loginIdentifier))
    {
        ModelState.AddModelError("loginIdentifier",
                    "The specified login identifier is invalid");
        return View();
    }
    else
    {
        var openid = new OpenIdRelyingParty();
        IAuthenticationRequest request = openid.CreateRequest(
            Identifier.Parse(loginIdentifier));

        // Require some additional data
        request.AddExtension(new ClaimsRequest
        {
            BirthDate = DemandLevel.NoRequest,
            Email = DemandLevel.Require,
            FullName = DemandLevel.Require
        });

        return request.RedirectingResponse.AsActionResult();
    }
}

现在看起来比我从可下载示例中使用的内容更清晰,更易于阅读。 (我下载了最新版本,这是他们给出的示例 - 这是我在5个月前构建我的应用程序的相同示例。)

    [ValidateInput(false)]
    public ActionResult Authenticate(string returnUrl) {
        var response = openid.GetResponse();
        if (response == null) {
            // Stage 2: user submitting Identifier
            Identifier id;
            if (Identifier.TryParse(Request.Form["openid_identifier"], out id)) {
                try {
                    return openid.CreateRequest(Request.Form["openid_identifier"]).RedirectingResponse.AsActionResult();
                } catch (ProtocolException ex) {
                    ViewData["Message"] = ex.Message;
                    return View("Login");
                }
            } else {
                ViewData["Message"] = "Invalid identifier";
                return View("Login");
            }
        } else {
            // Stage 3: OpenID Provider sending assertion response
            switch (response.Status) {
                case AuthenticationStatus.Authenticated:
                    Session["FriendlyIdentifier"] = response.FriendlyIdentifierForDisplay;
                    FormsAuthentication.SetAuthCookie(response.ClaimedIdentifier, false);
                    if (!string.IsNullOrEmpty(returnUrl)) {
                        return Redirect(returnUrl);
                    } else {
                        return RedirectToAction("Index", "Home");
                    }
                case AuthenticationStatus.Canceled:
                    ViewData["Message"] = "Canceled at provider";
                    return View("Login");
                case AuthenticationStatus.Failed:
                    ViewData["Message"] = response.Exception.Message;
                    return View("Login");
            }
        }
        return new EmptyResult();
    }

现在该示例包含了太多我喜欢的if语句,并且我需要添加额外的处理(activity loggingchecking for new useradd to existing account),它开始变得真实凌乱非常快。

不幸的是,如果我重构我的代码看起来更像第一个例子,我就会遇到一个小问题。视图如何与此交互?我的意思是,它正在寻找openid.GetResponse(),但我该如何提交该回复?

就像我说的,如果我能让这个工作,它看起来好像比我现在的方式更清洁。

1 个答案:

答案 0 :(得分:3)

您不提交此回复。当您在其批准页面上单击批准或取消时,OpenID提供商会执行此操作。据我所知,这里发生的事情是,例如Google通过GET返回一堆数据,然后当你调用openid.GetResponse()时,DotNetOpenAuth会解析。

我发布了一个评论很高的基本OpenID for MVC实现,它还具有用户注册功能。您可以在http://mvcopenid.codeplex.com找到它。它仍然不如上面的样品那么干净,但我发现它很干净。我最终会重构,但我需要弄清楚如何很好地绕过MVC的模型绑定器,因为我不喜欢像Request.Form["openid_identifier"]这样的代码。