6

Come impone a un utente la riautenticazione prima di eseguire un'azione in MVC?Ri-autenticare l'utente nell'applicazione MVC per l'azione

Stiamo utilizzando l'autenticazione di Windows. Ci sono alcune azioni che vogliamo fare in modo che vengano eseguite dall'utente (e impedire ad altri utenti di eseguire quelle azioni se l'utente ha dimenticato di bloccare la propria workstation).

Idealmente mi piacerebbe solo essere in grado di scrivere un attributo che si estende Authorize:

namespace AuthTest.Controllers 
{ 
    [Authorize(Roles="MyApp")] 
    public class HomeController : Controller 
    {  
     public ActionResult Index() 
     { 
      // A regular action 
      return View(); 
     } 

     [ReAuthenticate] 
     public ActionResult CriticalAction() 
     { 
      // Do something important 
      return View(); 
     } 
    } 
} 

Sembra che posso forzare l'utente a inserire nuovamente le proprie credenziali da avere il costume ReAuthenticate attribuiscono emettere una risposta HTTP 401 nel metodo AuthorizeCore. Tuttavia, questo ha richiesto un po 'di inganno dal Html.ActionLink è stato l'invio di due richieste:

protected override bool AuthorizeCore(HttpContextBase httpContext) 
{ 
    bool ok = base.AuthorizeCore(httpContext); 
    if (!ok) return false; 

    if (httpContext.Session["ReAuthCnt"] == null) 
    { 
     httpContext.Session["ReAuthCnt"] = 1; 
     return false; 
    } 
    else if ((int) httpContext.Session["ReAuthCnt"] < 2) 
    { 
     httpContext.Session["ReAuthCnt"] = (int)httpContext.Session["ReAuthCnt"] + 1; 
     return false; 
    } 
    else 
    { 
     httpContext.Session["ReAuthCnt"] = 0; 
     return true; 
    } 
} 

C'è un modo migliore per ottenere la ri-autorizzazione?

+0

Che cosa si intende per autenticare nuovamente? –

+0

Perché vorresti? Se l'utente è autenticato, allora è, beh, autenticato. Potresti considerare OAuth se non puoi mantenere un'autenticazione. Forse se hai descritto un po 'di più il tuo problema, potremmo suggerire cosa fare. – griegs

+0

Ho aggiornato la domanda con ulteriori dettagli sullo scenario e su ciò che ho provato. – user2813199

risposta

0

Se l'utente sta eseguendo un POST, è possibile aggiungere un campo nome utente e password a tale modulo e quindi convalidare le credenziali con Active Directory nel controller o utilizzando un ActionFilter?

-2

è possibile ottenere un'idea da qui sto facendo base di ruolo Autorizzazione qui

[Authorize(Roles = "admin,superadmin")]//Controler Authorization 
     public class ControlController : Controller 
     { 

      [Authorize(Roles = "superadmin")]//action Authorization 
      public ActionResult youraction() 
      { 
       return View(); 
      } 
     } 
0

Se ti è consentito dal business di utilizzare in realtà una forma di nuovamente loro (in altre parole, avere una pagina si digita un nome utente e password in) allora puoi fare quanto segue.

ReauthorizeAttribute

// custom page where user does type user/pass 
private string revalidateLoginUrl = "/account/reauth"; 
private bool? hasReauthenticated = false; 

protected override bool AuthorizeCore(HttpContextBase httpContext) 
{ 
    var authUrl = HttpContext.Request.Url; 
    hasReauthenticated = httpContext.Session[authUrl] as bool? 

    // could be just (hasReauthenticated) 
    // this look a bit more readable 
    return (hasReauthenticated == true); 
} 

public override void OnAuthorization(AuthorizationContext filterContext) 
{ 
    if (filterContext == null) 
    { 
    throw new ArgumentNullException("filterContext"); 
    } 

    var isAuthorized = AuthorizeCore(filterContext.HttpContext); 

    var authUrl = filterContext.HttpContext.Request.Url; 
    filterContext.HttpContext.Session[authUrl] = false; 

    if (!isAuthorized) 
    { 
    HandleUnauthorizedRequest(filterContext); 
    } 
} 

protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
{ 
    // something like this 
    var fullUrl = validateLoginurl + "?returnUrl=" 
    + HttpUtility.UrlEncode(revalidaetLoginUrl); 

    filterContext.HttpContext.Response.Redirect(validateLoginUrl); 
} 

ReauthModel

public class ReauthModel 
{ 
    public string Username { get; set; } 
    public string Password { get; set; } 
    public string ReturnUrl { get; set; } 
} 

AccoountController.cs (Validate a username and password against Active Directory?)

using System.DirectoryServices.AccountManagement; 

public ActionResult Reauth(string returnUrl) 
{ 
    var model = new ReauthModel(); 
    model.ReturnUrl = returnUrl; 

    return View(model); 
} 

[ValidateAntiForgeryToken] 
public ActionResult Reauth(ReauthModel model) 
{ 
    using(PrincipalContext pc = new 
    PrincipalContext(ContextType.Domain, "YOURDOMAIN")) 
    { 
    // validate the credentials 
    bool isValid = pc.ValidateCredentials("myuser", "mypassword"); 
    if (isValid) 
    { 
     Session[model.ReturnUrl] = true; 
     return RedirectTolocal(model.ReturnUrl); 
    } 
    } 

    // not authenticated 
    return RedirectToAction("?"); 

    //or 
    model.Username = string.Empty; 
    model.Passsword = string.Empty; 

    return View(model); 
} 

penso che si possa immaginare in base alla ReauthModel ciò che la vista sarà simile.

Nota: questo dovrebbe essere utilizzato in aggiunta a qualsiasi altro AuthorizeAttribute di che si sta utilizzando, non al posto di. Poiché l'utente sta digitando il nome utente e la password su un sito Web, questo necessita di per utilizzare SSL (anche se è interno).

0

Mi avvicinerei a questo in un modo diverso. Sembra che ciò che VERAMENTE desideri sia un aumento temporaneo delle credenziali, simile a UAC o Sudo, ma sul tuo sito web. Probabilmente vorrai che, se è trascorso un certo periodo di tempo, l'utente deve inserire nuovamente le proprie credenziali per accedere a tali funzioni.

L'approccio che vorrei fare è creare un IPrincipal personalizzato che consente di aggiungere temporaneamente un ruolo specifico all'utente e scadere tale ruolo dopo un periodo di tempo. Questo non sarebbe legato ai ruoli assegnati dagli utenti come memorizzati nel database, se non per dire che solo gli utenti con un ruolo specifico possono essere elevati.

In questo modo, si può semplicemente eseguire un controllo della password, aggiungere il ruolo temporaneamente al elenco dei ruoli degli utenti, e quindi l'attributo di autorizzazione standard di loro sarà entrare.