【问题标题】:Missing Authorization header in Basic authentication基本身份验证中缺少授权标头
【发布时间】:2015-05-05 06:03:49
【问题描述】:

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

【问题讨论】:

  • 您确认客户端确实收到了 401 状态。有一个我不记得的“事情”,如果某些客户没有得到 401,他们就不会发送 Auth 标头。
  • 是的,客户端得到 401 状态码。我怀疑在 IIS 中启用混合表单和基本身份验证,我肯定需要表单身份验证
  • 好吧,我很惊讶。最后一个响应是 401 .. 您不会收到 401,然后是服务器 500 错误,因此可能会撤消对客户端的 401 信号。

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


【解决方案1】:

仅查看您的代码,我根本看不出它是如何运行的,无论是生产还是其他。

我建议它抛出您的代码正在吞噬的错误,因为下面的代码会关闭响应,然后尝试调用基本方法。

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

将是要走的路。呵呵。

【讨论】:

    猜你喜欢
    • 2019-09-24
    • 2012-10-02
    • 1970-01-01
    • 1970-01-01
    • 2014-02-10
    • 2019-06-14
    • 1970-01-01
    • 2012-01-14
    • 2017-04-14
    相关资源
    最近更新 更多