基本身份验证中缺少授权标头

时间:2015-03-04 09:50:35

标签: c# asp.net asp.net-mvc iis-7.5 basic-authentication

我使用以下代码在我的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();
    }
}

1 个答案:

答案 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();

将是要走的路。咄。