开发者

DotNetOpenAuth - How would the "View" interact with this

I've been looking at refactoring my login controller for better code readability. In doing so, I came across the Programmatic OpenID Relying Party example that looks like this

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();
    }
}

Now this looks heaps cleaner and easier to read than what I used from the downloadable examples. (I downloaded the most recent version and this is the example they give - which is the same example I built my app on 5 months ago.)

    [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();
    }

Now that example has too many if statements for my liking, and with the extra processing that I have to add in (activity logging and checking for new user or add to existing account), it starts getting really messy really quick.

Unfortunately, if I were to refactor my code to look more like the first example, I'm stuck on one small problem. How does the View interact with this? I mean, it's looking for openid开发者_开发技巧.GetResponse(), but how do I submit that response?

Like I said, if I can get this working, it looks as though it'll be a lot cleaner than my current way.


You don't submit this response. The OpenID provider does when you click approve or cancel on their approval page. As far as I understand what's going on here is that for example Google returns a bunch of data via GET and then DotNetOpenAuth parses when you call openid.GetResponse().

I've published a heavily commented basic OpenID for MVC implementation that also features user registration. You can find it at http://mvcopenid.codeplex.com. It's still not as clean as the upper sample, but I find it quite clean. I will refactor that eventually, but I'll need to figure out how to get around MVC's model binder nicely, because I don't like code like Request.Form["openid_identifier"].

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜