【问题标题】:WebAPI Basic Authentication Authorization Filter and machine keysWebAPI 基本认证授权过滤器和机器密钥
【发布时间】:2015-03-02 10:32:11
【问题描述】:

我正在使用[WebAPI Basic Authentication Authorization Filter] 授权用户使用我的简单 Web api 数据服务。

问题是:一切都在 localhost 上运行,但是当我将服务发布到网络 (http://www.mywebsite.com) 时,客户端应用程序总是得到“未授权”响应。

当从 localhost 切换到 web 时,这一行是我(在客户端)所做的全部更改

//client.BaseAddress = new Uri("http://localhost:11992/"); // on localhost work
  client.BaseAddress = new Uri("http://mywebsite.com/"); // returns 401 Unauthorized

尝试使用远程 IIS 管理器添加机器密钥,但同样的事情发生了。

在 system.web (web.config) 中引用此机器密钥

IIS上的认证方式如下

还是不行。显然我在这里遗漏了一些东西。

更新 我正在扩展基本身份验证。过滤器,稍后我将其应用于我的控制器操作(我从客户端访问的那个)

[MyBasicAuthenticationFilter]
public class DataController : RavenController { ... }

并在此自定义身份验证中。过滤有硬编码的用户名并通过

public class MyBasicAuthenticationFilter : BasicAuthenticationFilter
{

    public MyBasicAuthenticationFilter()
    { }

    public MyBasicAuthenticationFilter(bool active)
        : base(active)
    { }


    protected override bool OnAuthorizeUser(string username, string password, HttpActionContext actionContext)
    {
        if (username == "myuser" && password == "mypass")
            return true;
        else
            return false;
    }
}

从客户端(wpf 客户端)

client.BaseAddress = new Uri("http://mywebsite.com/");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
                Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(
                string.Format("{0}:{1}", "myuser", "mypass"))));

我很困惑,因为相同的代码在 localhost 上工作正常,但是当我发布代码并将这个 client.BaseAddress 更改为我的实际网站 url 时,它返回 401 错误。

【问题讨论】:

  • 您能否扩展您的代码示例以演示您如何尝试设置用户凭据? 401 未授权表示未提供凭据或提供的凭据无效。您正在验证的用户帐户是否存在于服务器上?注意:基本身份验证不使用机器密钥。
  • @Adrian,问题已更新
  • 您扩展的“WebAPI 基本身份验证授权过滤器”是什么?问题中的链接指向机器密钥图像。这是应该存在的正确链接吗:weblog.west-wind.com/posts/2013/Apr/18/…
  • 是的,这是正确的链接。
  • 你对这个问题做了哪些调试。您是否考虑过将任何日志记录添加到您的服务器端代码中? (我假设你不能远程调试)。特别是在BasicAuthenticationFilter 类的ParseAuthorizationHeader 方法中。我现在对可能原因的最佳猜测是,您部署到的服务器上的默认编码与您的本地开发人员不同。

标签: c# asp.net asp.net-web-api


【解决方案1】:

给定Rick Strahl's Web Log 的 BasicAuthenticationFilter 类使用系统的默认编码从授权标头中提取用户凭据。根据MSDN documentationEncoding.Default 属性:

不同的计算机可以使用不同的默认编码,并且 默认编码甚至可以在单台计算机上更改。所以, 数据从一台计算机流式传输到另一台计算机,甚至在 同一台计算机上的不同时间可能会被错误地翻译。 此外,默认属性返回的编码使用 将不支持的字符映射到字符的最佳回退 由代码页支持。由于这两个原因,使用默认 一般不推荐编码。确保编码字节 正确解码,您应该使用 Unicode 编码,例如 UTF8Encoding 或 UnicodeEncoding,带有前导码。另一种选择是 使用更高级别的协议以确保使用相同的格式 编码和解码。

根据所提供的信息,这是最有可能的代码行,它可能会根据您的代码部署到的服务器的配置给出不同的结果。

因此,我会考虑在BasicAuthenticationFilter 类的ParseAuthorizationHeader 方法中替换以下行:

authHeader = Encoding.Default.GetString(Convert.FromBase64String(authHeader));

使用以下代码:

Encoding iso88591 = Encoding.GetEncoding("iso-8859-1");
authHeader = iso88591.GetString(Convert.FromBase64String(authHeader));

iso-8859-1 将为您提供与所有发送基本身份验证标头的客户端的最佳兼容性。请参阅以下有关在进行 HTTP 基本身份验证时使用的推荐编码的 StackOverflow 问题:What encoding should I use for HTTP Basic Authentication?

或者,如果您是唯一从 WCF 客户端调用 API 的人,那么只需确保您使用与服务器将解码它的字符代码相同的字符代码对用户名和密码进行编码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-06
    • 1970-01-01
    • 2019-02-15
    • 1970-01-01
    • 2016-10-27
    • 1970-01-01
    • 1970-01-01
    • 2014-03-24
    相关资源
    最近更新 更多