我的任务是从我们的SharePoint网站通过电子邮件发送一些文件(不知道版本或托管,但可以查找)。作为快速测试,我访问了其中一个文件,创建了一个“任何具有链接的人都可以查看”的链接,并将其插入到代码中。此代码返回403。
使用Dropbox链接执行相同的操作可以正常工作。我已经证实可以从我们的网络之外,从我的手机,个人笔记本电脑等访问SP文件,因此实际上它是匿名的。显然,我缺少一个神奇的标题或其他东西。我怀疑重定向了,但是按照他们的指示,我仍然会收到403。
我需要共享链接的原因是,我们有一个“ EmailService”,它需要任何附件的URL。实际上是该代码失败了,但我可以在本地复制。
这是服务正在执行的操作:
private static void Download()
{
var webClient = new WebClient();
var data = webClient.DownloadData("https://oursharepointaddy.com/:i:/s/blah/funkyShareurlhere?e=somestuffhere&download=1");
}
[在Chrome中使用F12时,我注意到了重定向,因此我在下面的代码中进行了处理。它愉快地跟随302,然后是BOOM,403。
private static void DownloadII()
{
var uri = $"https://oursharepointaddy.com/:i:/s/blah/funkyShareurlhere?e=somestuffhere&download=1";
while (true)
{
var request = new HttpRequestMessage(HttpMethod.Post, uri);
var handler = new HttpClientHandler {AllowAutoRedirect = false};
var response = new HttpClient(handler).SendAsync(request).ConfigureAwait(false).GetAwaiter().GetResult();
var statusCode = (int) response.StatusCode;
if (statusCode >= 300 && statusCode <= 399)
{
var redirectUri = response.Headers.Location;
if (!redirectUri.IsAbsoluteUri)
{
redirectUri = new Uri(request.RequestUri.GetLeftPart(UriPartial.Authority) + redirectUri);
}
uri = redirectUri.AbsoluteUri;
continue;
}
if (response.IsSuccessStatusCode)
{
var data = response.Content.ReadAsStreamAsync().GetAwaiter().GetResult();
}
}
}
我还通过邮递员获得了403。浏览器似乎很好。即使在Chrome中采用隐身模式,也没问题。我尝试了各种标头(UserAgent和我在Chrome中监视的其他标头),添加并删除了download=1
。我很困惑。
原来是cookie。也不需要重定向跟随循环。只需将HttpClientHander
告诉UseCookies = true
即可。
private static void DownloadIV()
{
var uri = "https://oursharepointaddy.com/:i:/s/blah/funkyShareurlhere?e=somestuffhere&download=1";
var handler = new HttpClientHandler { AllowAutoRedirect = true, UseCookies = true };
var request = new HttpRequestMessage(HttpMethod.Get, uri);
var response = new HttpClient(handler).SendAsync(request).ConfigureAwait(false).GetAwaiter().GetResult();
var statusCode = (int)response.StatusCode;
if (response.IsSuccessStatusCode)
{
var data = response.Content.ReadAsStreamAsync().GetAwaiter().GetResult();
using (var stm = File.Create("downloaded.xlsx"))
{
data.Seek(0, SeekOrigin.Begin);
data.CopyTo(stm);
}
}
}
为了完整起见,这就是我的原始代码看起来也可以按预期工作的方式:
private static void DownloadII()
{
var uri = $"https://oursharepointaddy.com/:i:/s/blah/funkyShareurlhere?e=somestuffhere&download=1";
var handler = new HttpClientHandler {AllowAutoRedirect = false, UseCookies = true};
while (true)
{
var request = new HttpRequestMessage(HttpMethod.Post, uri);
var response = new HttpClient(handler).SendAsync(request).ConfigureAwait(false).GetAwaiter().GetResult();
var statusCode = (int) response.StatusCode;
if (statusCode >= 300 && statusCode <= 399)
{
var redirectUri = response.Headers.Location;
if (!redirectUri.IsAbsoluteUri)
{
redirectUri = new Uri(request.RequestUri.GetLeftPart(UriPartial.Authority) + redirectUri);
}
uri = redirectUri.AbsoluteUri;
continue;
}
if (response.IsSuccessStatusCode)
{
var data = response.Content.ReadAsStreamAsync().GetAwaiter().GetResult();
}
}
}