2010-07-12 3 views
1

J'ai une application MVC 2 sur laquelle chaque page nécessite une autorisation (sauf pour/Account/Logon), mais je préférerais qu'elle redirige vers "/ Compte/LogOn? ReturnUrl =/SomePage" pour authentifier l'utilisateur, qu'il afficherait simplement le formulaire de connexion à la place sur la page demandée par l'utilisateur afin que l'URL ne change pasRenvoyer la vue de connexion au lieu de la rediriger dans une application MVC 2 (site)

J'ai déjà un BaseController presque tous les autre contrôleur hérite que je l'utilise à d'autres fins où je suis en train de mettre déjà mon AuthorizeAttribute (modifié par souci de concision):

[Authorize(Roles = "Role1, Role2")] 
public class BaseController : Controller 
{ 

} 

Ma première pensée pour une solution habile serait de passer outre la classe AuthorizeAttribute d'une manière qui ressemblerait à quelque chose comme ceci:

public class AuthorizeWithLoginAttribute : AuthorizeAttribute 
{ 
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     //This doesn't work obviously 
     filterContext.Result = View("Logon"); 
    } 
} 

alors je pourrais simplement changer mon contrôleur ci-dessus pour:

[AuthorizeWithLogin(Roles = "Role1, Role2")] 
public class BaseController : Controller 
{ 

} 

Est il y a un moyen de faire ce travail? (Ceci est mon premier post FYI)

+0

vous voulez dire, au lieu de rediriger vers '/ Account/LogOn? ReturnUrl =/SomePage' vous voulez qu'il soit redirigé vers/Account/Logon pour l'autentication? –

+0

Je veux éviter complètement la redirection. Donc, si je visite www.monsite.com et que je dois être authentifié, alors il me montrera simplement un formulaire de connexion, pas de redirection vers/Compte/Connexion du tout ... en gros, montrez-moi la vue Connexion au lieu de la Vue d'index (le problème étant que la vue de connexion est sur un contrôleur différent) –

Répondre

0

Pouvez-vous faire quelque chose dans un contrôleur de base comme

if(!User.Identity.IsInRole("Role1", "Role2") 
{ 
    return View("Logon") 
} 
return; 
+0

Eh bien cela fonctionne totalement pour la moitié de la bataille! C'était mortellement évident, merci. Cependant maintenant je dois comprendre comment manipuler le poteau de forme de cette page. Je vais mettre à jour dans un peu après avoir expérimenté quelques –

+0

Btw ... votre code doit être modifié pour: if (! User.IsInRole ("Role1") &&! User.IsInRole ("Role2")) mais je savais ce que tu voulais dire –

0

Je ne sais pas si je suis censé répondre à ma propre question, mais je voulais poster la solution que Simon Hazelton a inspiré.

Mon BaseController classe (modifié à nouveau par souci de concision):

[Authorize(Roles = "Role1, Role2")] 
public class BaseController : Controller 
{ 
    protected override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     if (!User.IsInRole("Role1") && !User.IsInRole("Role2")) 
     { 
      filterContext.Result = View("LogonView"); 
     } 

     base.OnAuthorization(filterContext); 
    } 
} 

Et la forme dans la vue /Views/Shared/LogonView.aspx:
(ce qui est copié à partir du défaut/Vues/Comptes/Logon.aspx, avec le Html.BeingForm() modifié)

<% using (Html.BeginForm(new { action = "LogOn", controller = "Account", area = "", returnUrl = Request.Url.PathAndQuery })) 
    <%: Html.ValidationSummary(true, "Login was unsuccessful. Please correct the errors and try again.") %> 
    <div> 
     <fieldset> 
      <legend>Account Information</legend> 

      <div class="editor-label"> 
       <%: Html.LabelFor(m => m.UserName) %> 
      </div> 
      <div class="editor-field"> 
       <%: Html.TextBoxFor(m => m.UserName) %> 
       <%: Html.ValidationMessageFor(m => m.UserName) %> 
      </div> 

      <div class="editor-label"> 
       <%: Html.LabelFor(m => m.Password) %> 
      </div> 
      <div class="editor-field"> 
       <%: Html.PasswordFor(m => m.Password) %> 
       <%: Html.ValidationMessageFor(m => m.Password) %> 
      </div> 

      <div class="editor-label"> 
       <%: Html.CheckBoxFor(m => m.RememberMe) %> 
       <%: Html.LabelFor(m => m.RememberMe) %> 
      </div> 

      <p> 
       <input type="submit" value="Log On" /> 
      </p> 
     </fieldset> 
    </div> 
<% } %> 

la seule chose que je voudrais qu'il fasse mieux est de ne pas la situation de redirection d'origine lors de la connexion sans succès (puisque c'est vraiment juste poster à la normale méthode)

Questions connexes