Pracuję nad projektem ASP.NET MVC5, który ma włączone uwierzytelnianie formularzy. Projekt znajduje się obecnie w fazie testowej i jest hostowany online na platformie Azure, ale właściciel projektu chciałby wyłączyć cały publiczny dostęp do witryny (ponieważ niektóre części witryny nie wymagają w ogóle uwierzytelniania użytkownika).Podstawowe uwierzytelnianie HTTP ASP.NET MVC5 i wyjątek AntiForgeryToken
W tej fazie testowej zdecydowaliśmy się wdrożyć podstawowe uwierzytelnianie HTTP, od tego link. Zmieniłem kod, więc lepiej pasuje do moich potrzeb:
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"));
}
}
}
Ja również zarejestrował go jako filtr globalnej:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorExtendedAttribute());
filters.Add(new BasicAuthenticationAttribute(AppConfig.BasicUsername, AppConfig.BasicPassword));
}
}
Jednakże istnieją pewne problemy, kiedy uruchomić projekt . Jeśli używam tej wersji kodu:
if (!alreadySent)
{
res = filterContext.HttpContext.Response;
res.StatusCode = 401;
res.AppendHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", BasicRealm ?? "Test"));
}
po pomyślnym zalogowaniu się stale przekierowuje do strony logowania formularzy.
Jednak gdybym dołączyć
res.End();
po
res.AppendHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", BasicRealm ?? "Test"));
Antiforgerytoken w plikach cshtml rzuca System.Web.HttpException
Server nie może dołączyć nagłówek po nagłówki HTTP zostały wysłane.
Ale w tym przypadku ostatecznie pomyślnie uwierzytelnia.
Obecnie utknąłem na tym i nie mam pojęcia, jak rozwiązać ten problem, ponieważ wyłączanie uwierzytelniania formularzy nie jest i opcja i nie mogę usunąć wszystkich AntiForgeryTokens i ich sprawdzania poprawności.
Dlaczego wybraliście to podejście?Jeśli chcesz zbudować niestandardowy filtr uwierzytelniania, powinieneś dziedziczyć po 'AuthorizeAttribute', przesłonić funkcję' IsAuthorized', zwrócić 'false' dla nieautoryzowanych żądań i obsłużyć je w funkcji' HandleUnauthorizedRequest'. – AnhTriet
Jeśli zmienisz wiersz res.StatusCode wierszem res.AppendHeader, co by się stało? Czy wartość StatusCode jest liczona jako część "Body" tak, że zamyka nagłówki od zapisania? Proszę również rozważyć odpowiedź Andrew poniżej. –
plz nie używaj podstawowego uwierzytelnienia. Zauważ, że inne pytanie, do którego się odwołujesz, ma już 6 lat, i nawet wtedy były lepsze alternatywy. Zobacz: http://adrianotto.com/2013/02/why-http-basic-auth-is-bad/ – nothingisnecessary