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"]
.
精彩评论