Sto lavorando al progetto ASP.NET MVC5 che ha l'autenticazione dei moduli abilitata. Il progetto è attualmente in fase di test e ospitato online su Azure, ma il proprietario del progetto vorrebbe disabilitare tutti gli accessi pubblici al sito (poiché alcune parti del sito non richiedono l'autenticazione dell'utente).ASP.NET MVC5 Autenticazione HTTP di base e AntiForgeryToken exception
Per questa fase di test, abbiamo deciso di implementare l'autenticazione HTTP di base, da questo link. Ho cambiato il codice, quindi è meglio adatta alle mie esigenze:
public class BasicAuthenticationAttribute : FilterAttribute, IAuthorizationFilter
{
public string BasicRealm { get; set; }
protected string Username { get; set; }
protected string Password { get; set; }
public BasicAuthenticationAttribute(string username, string password)
{
this.Username = username;
this.Password = password;
}
public void OnAuthorization (AuthorizationContext filterContext)
{
var req = filterContext.HttpContext.Request;
var auth = req.Headers["Authorization"];
if (!String.IsNullOrEmpty(auth))
{
var cred = System.Text.ASCIIEncoding.ASCII.GetString(Convert.FromBase64String(auth.Substring(6))).Split(':');
var user = new { Name = cred[0], Pass = cred[1] };
if (user.Name == Username && user.Pass == Password)
return;
}
var res = filterContext.HttpContext.Response;
var alreadySent = HttpContext.Current.Items.Contains("headers-sent");
if (!alreadySent)
{
res = filterContext.HttpContext.Response;
res.StatusCode = 401;
res.AppendHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", BasicRealm ?? "Test"));
}
}
}
ho anche registrato come un filtro globale:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorExtendedAttribute());
filters.Add(new BasicAuthenticationAttribute(AppConfig.BasicUsername, AppConfig.BasicPassword));
}
}
Tuttavia, ci sono alcuni problemi quando ho eseguito il progetto . Se utilizzo questa versione di codice:
if (!alreadySent)
{
res = filterContext.HttpContext.Response;
res.StatusCode = 401;
res.AppendHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", BasicRealm ?? "Test"));
}
dopo il login con successo esso reindirizza costantemente alla pagina di accesso moduli.
Tuttavia, se aggiungo
res.End();
dopo
res.AppendHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", BasicRealm ?? "Test"));
Antiforgerytoken in file cshtml tiri System.Web.HttpException
Server non è possibile accodare intestazione dopo intestazioni HTTP sono stati inviato.
Ma in questo caso, si autentica alla fine con successo.
Attualmente sono bloccato su questo e non ho idea di come risolvere questo problema, dal momento che disattivare l'autenticazione dei moduli non è e l'opzione, e non riesco a rimuovere tutti AntiForgeryTokens e la loro convalida.
Perché avete scelto questo approccio?Se si desidera creare un 'Filtro di autenticazione personalizzato ', si dovrebbe ereditare da' AuthorizeAttribute', sovrascrivere la funzione 'IsAuthorized', restituire' false' per le richieste non autorizzate e gestirle nella funzione 'HandleUnauthorizedRequest'. – AnhTriet
Se si capovolge la riga res.StatusCode con la riga res.AppendHeader cosa succederebbe? Il valore StatusCode conta come parte del "Corpo" in modo da chiudere le intestazioni da non essere più scritte? Inoltre, si prega di considerare la risposta di Andrew qui sotto. –
plz non utilizzare l'autenticazione di base. Tieni presente che l'altra domanda a cui fai riferimento è uguale a 6 anni, e anche allora c'erano alternative migliori. Vedi: http://adrianotto.com/2013/02/why-http-basic-auth-is-bad/ – nothingisnecessary