我使用以下代码在我的ASP.Net MVC应用程序中实现基本身份验证过滤器。一切都在本地机器上运行良好,而它在生产服务器中不起作用,并且它会一直提示登录框,因为Request.Headers["Authorization"]
为空。
我使用fiddler为此请求获取标头,Authorization
标头符合预期值。我不知道为什么Request.Headers["Authorization"]
总是为空:|
我还创建了一个新项目,只有这个过滤器和一个控制器并在服务器上发布,猜猜是什么!它的工作......
public class RequireBasicAuthenticationAttribute : ActionFilterAttribute
{
public string BasicRealm { get; set; }
protected string Username { get; set; }
protected string Password { get; set; }
public RequireBasicAuthenticationAttribute()
{
this.Username = System.Configuration.ConfigurationManager.AppSettings["ProtectedUsername"];
this.Password = System.Configuration.ConfigurationManager.AppSettings["ProtectedPassword"];
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var req = filterContext.HttpContext.Request;
var auth = req.Headers["Authorization"];
auth.LogText();
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 (Username.Equals(user.Name, StringComparison.InvariantCultureIgnoreCase) && Password.Equals(user.Pass)) return;
}
var res = filterContext.HttpContext.Response;
res.StatusCode = 401;
res.AddHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", BasicRealm ?? "bimeh-takmili"));
res.End();
}
}
答案 0 :(得分:0)
只看你的代码,我就不知道它是如何运行的,无论是生产还是其他方式。
我建议它抛出一个错误,您的代码正在吞咽,因为下面的代码会关闭响应,然后尝试调用基本方法。
public override void ExecuteResult(ControllerContext context)
{
if (context == null) throw new ArgumentNullException("context");
// this is really the key to bringing up the basic authentication login prompt.
// this header is what tells the client we need basic authentication
var res = context.HttpContext.Response;
res.StatusCode = 401;
res.AddHeader("WWW-Authenticate", "Basic");
res.End();
base.ExecuteResult(context);
}
你不能这样做,代码会抛出一个错误:
在发送HTTP标头后,服务器无法设置状态。
由于它会抛出错误(我认为)并被反弹,因此可能无法输出401状态响应。 " WWW-Authenticate"标题仍然被发送,但这就是你得到一个对话框的原因。
凭证对话框会在" WWW-Authenticate"被检测到但如果它从上一个响应中收到401状态,它将仅在请求中发回Authorization
标头。
所以,如果你放弃:
base.ExecuteResult(context);
从您的代码中,会发生什么?
修改强>
实际上放弃了
res.End();
将是要走的路。咄。