2010-11-29 35 views
2

J'ai réfléchi à la refactorisation de mon contrôleur de connexion pour une meilleure lisibilité du code. Ce faisant, je suis tombé sur le Programmatic OpenID Relying Party example qui ressemble à ceciDotNetOpenAuth - Comment le "View" interagirait avec ceci

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

Maintenant, cela ressemble tas plus propre et plus facile à lire que ce que je les exemples téléchargeables. (Je l'ai téléchargé la version la plus récente et c'est l'exemple qu'ils donnent -. Qui est le même exemple, je construit mon application sur il y a 5 mois)

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

Maintenant, cet exemple a trop si les déclarations à mon goût, et avec le traitement supplémentaire que je dois ajouter (activity logging et checking for new user ou add to existing account), il commence à devenir vraiment salissant vraiment vite.

Malheureusement, si je devais refactoriser mon code pour ressembler davantage au premier exemple, je suis bloqué sur un petit problème. Comment la vue interagit-elle avec cela? Je veux dire, il cherche openid.GetResponse(), mais comment puis-je soumettre cette réponse? Comme je l'ai dit, si je peux obtenir ce travail, il semble que ce sera beaucoup plus propre que mon chemin actuel.

+0

Comment avez-vous obtenu la dernière ligne de travail? 'return request.RedirectingResponse.AsActionResult();' J'ai ajouté un certain nombre d'utilisations d'espaces de noms, mais je ne peux pas déterminer comment faire progresser cette partie. HttpRequestBase ne contient pas de référence pour RedirectingResponse. – zeristor

Répondre

3

Vous ne soumettez pas cette réponse. Le fournisseur OpenID le fait lorsque vous cliquez sur Approuver ou Annuler sur sa page d'approbation. Pour autant que je comprenne ce qui se passe ici est que par exemple Google renvoie un tas de données via GET, puis DotNetOpenAuth analyse lorsque vous appelez openid.GetResponse().

J'ai publié une implémentation OpenID pour MVC de base fortement commentée, qui inclut également l'enregistrement d'utilisateur. Vous pouvez le trouver au http://mvcopenid.codeplex.com. Ce n'est pas aussi propre que l'échantillon supérieur, mais je le trouve très propre. Je vais refactoriser cela finalement, mais je vais devoir trouver comment contourner joliment le classeur modèle de MVC, parce que je n'aime pas le code comme Request.Form["openid_identifier"].

+1

Hé, ça a l'air vraiment cool. Je vais le vérifier! –

+0

Savez-vous si nous pouvons également obtenir le "nom du fournisseur" en même temps? Dans mon application, vous pouvez avoir des OpenID associés illimités, donc je voudrais me référer au fournisseur auquel chaque connexion est associée. –

+0

Voulez-vous dire un joli nom pour un fournisseur? Je n'ai pas encore essayé, mais je ne pense pas que ce soit possible avec SimpleRegistration. Je pense que la plupart des clients utilisent une liste pour de jolis noms. Mais comme je l'ai dit, je n'ai pas encore creusé ça. – gligoran