简体   繁体   English

WebAPI基本身份验证授权过滤器和机器密钥

[英]WebAPI Basic Authentication Authorization Filter and machine keys

I'm using [WebAPI Basic Authentication Authorization Filter] to authorize users on consuming my simple web api data service. 我正在使用[WebAPI基本身份验证授权过滤器]授权用户使用我的简单Web api数据服务。

Question is: everything work on localhost but when I publish my service to the web ( http://www.mywebsite.com ) client app always gets "Unauthorize" response. 问题是:一切都可以在localhost上运行,但是当我将服务发布到Web( http://www.mywebsite.com )时,客户端应用程序始终会收到“未经授权”响应。

This line is all I change (on client side) when switching from localhost to the web 从本地主机切换到网络时,这行是我更改的所有内容(在客户端)

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

Tried with adding machine key using remote IIS manager but same thing happens. 尝试使用远程IIS管理器添加计算机密钥,但是发生了同样的事情。

在此处输入图片说明

reference this machine key in system.web (web.config) 在system.web(web.config)中引用此机器密钥 在此处输入图片说明

and authentication mode on IIS is as follows IIS上的身份验证模式如下

在此处输入图片说明

Still doesnt work. 仍然不起作用。 Obviously I'm missing something here. 显然我在这里错过了一些东西。

UPDATE I'm extending basic auth. 更新我正在扩展基本身份验证。 filter which I later apply on my controller action (the one I access from client side) 稍后我将其应用于控制器操作的过滤器(我从客户端访问的过滤器)

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

and inside this custom auth. 并在此自定义身份验证中。 filter there is hardcoded username and pass 过滤有硬编码的用户名并通过

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;
    }
}

and from client side (wpf client) 并从客户端(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"))));

I'm confused because same code work fine on localhost but when I publish code and change this client.BaseAddress to my actual website url it returns 401 error. 我很困惑,因为相同的代码在localhost上可以正常工作,但是当我发布代码并将此client.BaseAddress更改为我的实际网站url时,它返回401错误。

The BasicAuthenticationFilter class given Rick Strahl's Web Log uses the System's default encoding to extract the user credentials from the authorization header. Rick Strahl的Web日志指定的BasicAuthenticationFilter类使用系统的默认编码从授权标头中提取用户凭证。 As per the MSDN documentation for the Encoding.Default property: 根据Encoding.Default属性的MSDN文档

Different computers can use different encodings as the default, and the default encoding can even change on a single computer. 不同的计算机可以使用不同的编码作为默认编码,并且甚至可以在一台计算机上更改默认编码。 Therefore, data streamed from one computer to another or even retrieved at different times on the same computer might be translated incorrectly. 因此,从一台计算机流向另一台计算机或什至在同一台计算机上不同时间检索的数据可能会错误地转换。 In addition, the encoding returned by the Default property uses best-fit fallback to map unsupported characters to characters supported by the code page. 此外,由Default属性返回的编码使用最适合的后备方式将不支持的字符映射到代码页支持的字符。 For these two reasons, using the default encoding is generally not recommended. 由于这两个原因,通常不建议使用默认编码。 To ensure that encoded bytes are decoded properly, you should use a Unicode encoding, such as UTF8Encoding or UnicodeEncoding, with a preamble. 为确保对编码的字节进行正确的解码,应将Unicode编码(例如UTF8Encoding或UnicodeEncoding)与前导一起使用。 Another option is to use a higher-level protocol to ensure that the same format is used for encoding and decoding. 另一种选择是使用更高级别的协议,以确保使用相同的格式进行编码和解码。

Based on the information provided, this is the mostly likely line of code which can potentially give different results based on the configuration of the server your code is deployed to. 根据提供的信息,这是最可能的代码行,根据代码部署到的服务器的配置,这些代码可能会给出不同的结果。

I would therefore consider replacing the following line in the ParseAuthorizationHeader method of the BasicAuthenticationFilter class: 因此,我将考虑替换BasicAuthenticationFilter类的ParseAuthorizationHeader方法中的以下行:

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

with the following code: 使用以下代码:

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

iso-8859-1 will give you best compatibility with all clients that send basic authentication header. iso-8859-1将为您与所有发送基本身份验证标头的客户端提供最佳兼容性。 See the following StackOverflow question on the recommend encoding to use when doing HTTP Basic Authentication: What encoding should I use for HTTP Basic Authentication? 请参阅以下有关在进行HTTP基本身份验证时使用的推荐编码的StackOverflow问题: 我应该对HTTP基本身份验证使用哪种编码?

Alternatively if you're the only one who will be calling the API from your WCF client, then just make sure you're encoding the username and password in the same character code as the server will be decoding it in. 另外,如果您是唯一一个从WCF客户端调用API的人,则只需确保您使用与服务器将对其进行解码相同的字符代码对用户名和密码进行编码即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM