tôi đang làm việc trên dự án ASP.NET MVC5 trong đó có hình thức xác thực được kích hoạt. Dự án hiện đang trong giai đoạn thử nghiệm, và lưu trữ trực tuyến trên Azure, nhưng chủ dự án muốn vô hiệu hóa tất cả các truy cập công cộng vào trang web (vì một số phần của trang web không yêu cầu cho người sử dụng để xác thực ở tất cả).ASP.NET MVC5 Basic xác thực HTTP và AntiForgeryToken ngoại lệ
Đối với giai đoạn thử nghiệm này, chúng tôi đã quyết định để thực hiện xác thực HTTP cơ bản, từ link này. Tôi đã thay đổi mã, do đó phù hợp hơn với nhu cầu của tôi:
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"));
}
}
}
Tôi cũng đã đăng ký nó như một bộ lọc toàn cầu:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorExtendedAttribute());
filters.Add(new BasicAuthenticationAttribute(AppConfig.BasicUsername, AppConfig.BasicPassword));
}
}
Tuy nhiên, có một số vấn đề khi tôi chạy dự án . Nếu tôi sử dụng phiên bản mã này:
if (!alreadySent)
{
res = filterContext.HttpContext.Response;
res.StatusCode = 401;
res.AppendHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", BasicRealm ?? "Test"));
}
sau khi đăng nhập thành công, nó liên tục chuyển hướng đến trang đăng nhập biểu mẫu.
Tuy nhiên nếu tôi thêm
res.End();
sau
res.AppendHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", BasicRealm ?? "Test"));
Antiforgerytoken trong các tập tin cshtml ném System.Web.HttpException
Server không thể thêm tiêu đề sau khi tiêu đề HTTP đã gởi.
Nhưng trong trường hợp này, cuối cùng xác thực thành công.
Tôi hiện đang bị mắc kẹt về vấn đề này và không biết cách giải quyết vấn đề này vì việc tắt xác thực biểu mẫu không phải là tùy chọn và tôi không thể xóa tất cả AntiForgeryTokens và xác thực của chúng.
Tại sao bạn chọn phương pháp này?Nếu bạn muốn xây dựng một 'Bộ lọc xác thực 'tùy chỉnh, bạn nên kế thừa từ' AuthorizeAttribute', ghi đè hàm 'IsAuthorized', trả về' false' cho các yêu cầu trái phép và xử lý chúng trong hàm 'HandleUnauthorizedRequest'. – AnhTriet
Nếu bạn lật res.StatusCode dòng với res.AppendHeader dòng những gì sẽ xảy ra? Giá trị StatusCode có được tính là một phần của "Nội dung" để đóng các Tiêu đề không được viết nữa không? Ngoài ra xin vui lòng xem xét phản ứng của Andrew dưới đây. –
plz không sử dụng auth cơ bản. Lưu ý rằng câu hỏi khác mà bạn tham khảo giống như 6 tuổi, và thậm chí sau đó đã có lựa chọn thay thế tốt hơn. Xem: http://adrianotto.com/2013/02/why-http-basic-auth-is-bad/ – nothingisnecessary