2015-01-24 4 views
6

Sto utilizzando ASP.NET MVC 5 e WebApi 2 e sto provando a eseguire un accesso Ajax con reindirizzamento in caso di esito positivo.Identità ASP.NET WebApi 2 vs MVC 5 Accedi ai cookie

Per l'autenticazione, utilizzo le librerie di identità ASP.NET fornite per impostazione predefinita per un nuovo progetto MVC ASP.NET.

Ho ottenuto tutto funzionante e tutto è andato bene con MVC 5. Ma per la vita di me, non riesco a ottenere il controller MVC standard per restituire solo JSON semplice. (Avvolge il mio JSON Voglio tornare in un oggetto padre) sì, potrei sistemarlo sul lato client, ma per me è un hacker.

Un'altra opzione che mi sembra migliore è utilizzare WebApi che restituisce gli oggetti come me li aspetto (solo il mio JSON come corpo). Ma il problema che sto avendo è che l'identità di ASP.NET SignInManager non sta inviando i cookie .ASPNet.Identity, a meno che non restituisca un ActionResult.

Il sotto è il mio controller WebAPI, che sta tornando corretta prevede JSON minima, ma non invia i comandi Set-Cookie, quindi ogni reindirizzamento vede l'utente non loggato.

[Authorize] 
public class AccountController : ApiController 
{ 
    public AccountController(IApplicationSignInManager signInManager) 
    { 
     SignInManager = signInManager; 
    } 

    public IApplicationSignInManager SignInManager {....} 

    // 
    // POST: /Account/Login 
    [HttpPost] 
    [AllowAnonymous] 
    [NgValidateAntiForgeryToken] 
    public async Task<HttpResponseMessage> Login(LoginViewModel model) 
    { 
     // Temporarily using Dynamic 
     dynamic res = new ExpandoObject(); 

     // This doesn't count login failures towards account lockout 
     // To enable password failures to trigger account lockout, change to shouldLockout: true 
     var status = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false); 

     res.status = status.ToString(); 

     return new HttpResponseMessage(HttpStatusCode.OK) 
     { 
      Content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(res)) 
     }; 
    } 
} 

che restituisce il seguente JSON ma nessun cookie:

{"status":"Success"} 

Se cambio questo per restituire un ActionResult piuttosto che HttpResponseMessage, i comandi Set-cookie vengono inviati, ma il JSON è avvolto all'interno proprietà aggiuntive.

public async Task<ActionResult> Login(LoginViewModel model) 
    { 
     // Temporarily using Dynamic 
     dynamic res = new ExpandoObject(); 

     // This doesn't count login failures towards account lockout 
     // To enable password failures to trigger account lockout, change to shouldLockout: true 
     var status = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false); 

     res.status = status.ToString(); 

     return new JsonResult{Data = res}; 
    } 

che restituisce i cookie, ma avvolto JSON:

{"contentEncoding":null,"contentType":null,"data":{"status":"Success"},"jsonRequestBehavior":1,"maxJsonLength":null,"recursionLimit":null} 

Ora sto indovinando che la sua sta accadendo perché il SignInManager probabilmente assegnando i biscotti a HttpContext.Current.Response oggetto, che è stato generato in precedenza. E quando restituisco un JsonResult, ASP.NET collega questo risultato a HttpContext.Current.Response e invia al client, quindi con i cookie.

Tuttavia, quando restituisco HttpResponseMessage, ASP.NET restituisce HttpResponse appena creato, che non dispone dei cookie SignInManager. Ho ragione di pensarlo?

EDIT 1: come suggerito da @ David Tansey ho provato quanto segue, che ancora non impostare i cookie, ma i rendimenti corretti JSON

public async Task<IHttpActionResult> Login(LoginViewModel model) 
    {    
     var status = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false); 

     return Json(new {status = status.ToString()}); 
    } 

ritorni corretto JSON, ma nessun cookie:

{"status":"Success"} 

FIX: Dopo @David Tansey ha sottolineato utilizzando un nuovo tipo anonimo {}, ho deciso di provarlo.E i due metodi seguenti lavorare

MVC

dovuto restituire un ActionResult/JsonResult, per il quale tutti i campi ad eccezione di quelli erano nulli, e ha dovuto restituire un tipo Anonymous piuttosto che una dinamica ExpandoObject() come la dinamica oggetto stava causando il serializzatore a gonfiare restituita JSON

[HttpPost] 
    [AllowAnonymous] 
    [NgValidateAntiForgeryToken] 
    public async Task<ActionResult> Login(LoginViewModel model) 
    { 
     var status = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false); 

     //return Json(new {status = status.ToString()}); 
     // OR 
     return new JsonResult { Data = new { status = status.ToString() } }; 
    } 

WebAPI 2

Doveva cambiare il tipo di ritorno in oggetto, che in viene serializzato su Json e imposta anche i cookie. Restituendo un HttpResponseMessage, i cookie che SignInManager hanno impostato si perdono, suppongo che inizi utilizzando l'oggetto di risposta appena restituito.

[HttpPost] 
    [AllowAnonymous] 
    [NgValidateAntiForgeryToken] 
    public async Task<object> Login(LoginViewModel model) 
    { 
     var status = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false); 

     return new {status = status.ToString()}; 
    } 
+0

io non sono sicuro di quello che stai chiedendo circa. Puoi per favore riformulare la tua domanda? – trailmax

+0

Aggiunto codice di esempio, fondamentalmente usando MVC.ActionResult = Cookie ma JSON avvolto, ma WebApi.HttpResponseMessage = Nessun cookie ma corretto JSON –

+0

Se non ti piace cosa 'JsonResult()' avvolge i tuoi dati, perché non usare semplicemente 'Json (oggetto) 'metodo invece? Qualcosa come, 'return Json (new {status = res});' –

risposta