我正在处理一个启用表单身份验证的ASP.NET MVC5项目。该项目目前处于测试阶段,在Azure上托管在线,但是项目所有者希望禁用对站点的所有公共访问(因为站点的某些部分根本不需要用户进行身份验证)。
在这个测试阶段,我们决定实现基本的HTTP身份验证,参考了这个链接。我修改了代码,以更好地满足我的需求:
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"));
}
}
}
我也将其注册为全局过滤器:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorExtendedAttribute());
filters.Add(new BasicAuthenticationAttribute(AppConfig.BasicUsername, AppConfig.BasicPassword));
}
}
然而,当我运行项目时,出现了一些问题。如果我使用这个版本的代码:
if (!alreadySent)
{
res = filterContext.HttpContext.Response;
res.StatusCode = 401;
res.AppendHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", BasicRealm ?? "Test"));
}
在成功登录后,它会不断地重定向到表单登录页面。然而,如果我附加:
res.End();
之后
res.AppendHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", BasicRealm ?? "Test"));
cshtml文件中的Antiforgerytoken引发System.Web.HttpException异常
HTTP标头已发送后,服务器无法附加标头。
但在这种情况下,它最终成功验证。
我目前被困在这个问题上,不知道如何解决,因为关闭表单身份验证不是一个选项,而且我不能删除所有AntiForgeryTokens及其验证。
AuthorizeAttribute
,重写IsAuthorized
函数,在未经授权的请求中返回false
并在HandleUnauthorizedRequest
函数中处理它们。 - Triet Doan