PUT 文件上传时摘要式身份验证失败

Digest Authentication fails with PUT file upload

我正在尝试将文件上传到此服务中的 API 信息之后。 Easy Post API

我能够成功发送带有摘要身份验证的第一个 GET 请求。

我在尝试使用“PUT”上传文件时收到 403 - 未经授权。

这是我的代码。我正在使用自定义 Web 客户端在 Web 请求中设置参数。

public class CustomWebClient : WebClient
{

    private BingMailConfigOptions ConfigOptions;

    public CustomWebClient(BingMailConfigOptions configOptions) : base()
    {
        ConfigOptions = configOptions;
    }

    protected override WebRequest GetWebRequest(Uri address)
    {
        var request = (HttpWebRequest)base.GetWebRequest(address);

        request.ServicePoint.Expect100Continue = false;
        request.Method = "PUT";
        request.Credentials = GetCredentialCache(address, ConfigOptions);

        return request;
    }

    public static CredentialCache GetCredentialCache(Uri uri, BingMailConfigOptions options)
    {
        var credentialCache = new CredentialCache
        {
            {
            new Uri(uri.GetLeftPart(UriPartial.Authority)), 
            "Digest",
            new NetworkCredential(options.AuthUserName, options.AuthPassword, uri.GetLeftPart(UriPartial.Authority))
            }
        };
        return credentialCache;
    }
}

// in a separate class. 
private void Upload(string sessionId, string filePath)
{
    _log.Trace("Trying to upload the file: " + filePath);
    var file = new FileInfo(filePath);

    if (file.Exists)
    {

        using (var uploader = new CustomWebClient(ConfigOptions))
        {
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
            Uri uri = new Uri("https://bingmail.com.au/" + "direct_upload/{0}/{1}"(sessionId, HttpUtility.UrlEncode(file.Name))); 
            uploader.UploadFile(uri, "PUT", filePath);
        } 
    }
    else
    {
        throw new Exception("File Not found");
    }
}

你能告诉我我做错了什么或指出正确的方向吗?

谢谢

我终于想出了解决办法。希望有一天它能对某人有所帮助。

除了一些 easy-to-figure-out 方法之外的完整解决方案已发布在此要点中。 Bing-Mail Easy Post Api - Version 1.3

我所做的是从 https://whosebug.com/a/3117042/959245 修改 DigestAuthFixer 以支持任何 HTTP 方法。

然后用它来创建 session,当我们使用 DigestAuthFixer 创建 session 时,它会存储 Digest-Auth headers,我可以在正在上传文件。

 using (var client = new WebClient())
{
    var uri = new Uri(_easypostHosts[2] + UploadUri.FormatWith(sessionId, HttpUtility.UrlEncode(fileName)));

    // get the auth headers which are already stored when we create the session
    var digestHeader = DigestAuthFixer.GetDigestHeader(uri.PathAndQuery, "PUT");
    // add the auth header to our web client
    client.Headers.Add("Authorization", digestHeader);

    // trying to use the UploadFile() method doesn't work in this case. so we get the bytes and upload data directly 
    byte[] fileBytes = File.ReadAllBytes(filePath);

    // as a PUT request
    var result = client.UploadData(uri, "PUT", fileBytes);

    // result is also a byte[].
    content = result.Length.ToString();
}