远程服务器返回错误:(403)禁止访问。

35

我编写了一个应用程序,在过去的几个月中一直运行良好,但最近几天仅在安装版本上出现以下错误。

如果我在VS中运行源代码,一切都正常。此外,bin文件夹中的.exe文件也可以正常工作。只有安装版本会生成错误,如果我重新编译和重新安装,则会得到相同的错误。

我对导致这种情况的原因有些糊涂,并希望能获得一些指针。似乎通过IE进行的WebRequest响应未被返回,但我对为什么在VS中没有任何错误的情况感到困惑。是否存在任何新的IE安全措施/策略可能导致此问题?

我已经尝试过的事情包括:

  • 禁用所有防病毒软件和防火墙
  • 以管理员身份运行

异常:

Exception: System.Windows.Markup.XamlParseException: The invocation of the constructor on type 'XApp.MainWindow' that matches the specified binding constraints threw an exception. ---> System.Net.WebException: The remote server returned an error: (403) Forbidden.
   at System.Net.HttpWebRequest.GetResponse()
   at XApp.HtmlRequest.getHtml(Uri uri) in J:\Path\MainWindow.xaml.cs:line 3759
   at XApp.MainWindow.GetLinks() in J:\Path\MainWindow.xaml.cs:line 2454
   at XApp.MainWindow..ctor() in J:\Path\MainWindow.xaml.cs:line 124
   --- End of inner exception stack trace ---
   at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
   at System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri)
   at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
   at System.Windows.Application.LoadBamlStreamWithSyncInfo(Stream stream, ParserContext pc)
   at System.Windows.Application.LoadComponent(Uri resourceLocator, Boolean bSkipJournaledProperties)
   at System.Windows.Application.DoStartup()
   at System.Windows.Application.<.ctor>b__1(Object unused)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
Exception: System.Net.WebException: The remote server returned an error: (403) Forbidden.
   at System.Net.HttpWebRequest.GetResponse()
   at XApp.HtmlRequest.getHtml(Uri uri) in J:\Path\MainWindow.xaml.cs:line 3759
   at XApp.MainWindow.GetLinks() in J:\Path\MainWindow.xaml.cs:line 2454
   at XApp.MainWindow..ctor() in J:\Path\MainWindow.xaml.cs:line 124

编辑:

这是一个独立的应用程序安装。当我以管理员身份运行时,我打开了程序文件夹,并运行了exe文件而不是快捷方式。

导致问题的代码是这个:

private void GetLinks()
{
    //Navigate to front page to Set cookies
    HtmlRequest htmlReq = new HtmlRequest();

    OLinks = new Dictionary<string, List<string>>();

    string Url = "http://www.somesite.com/somepage";
    CookieContainer cookieJar = new CookieContainer();
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
    request.CookieContainer = cookieJar;

    request.Accept = @"text/html, application/xhtml+xml, */*";
    request.Referer = @"http://www.somesite.com/";
    request.Headers.Add("Accept-Language", "en-GB");
    request.UserAgent = @"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)";
    request.Host = @"www.somesite.com";

    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    String htmlString;
    using (var reader = new StreamReader(response.GetResponseStream()))
    {
        htmlString = reader.ReadToEnd();
    }

    //More Code


 }

1
首先,你的代码是什么?如果我是你,我会尝试使用Fiddler监视HTTP消息,并比较工作和不工作的请求。 - Steve B
1
你是如何运行你的“已安装版本”的 - 作为服务还是普通的控制台/桌面应用程序?你应该尝试验证应用程序在哪个用户上下文中运行。你能详细说明一下你以管理员身份运行应用程序的具体步骤吗?请提供更多关于你的应用程序架构的细节 - 建立了哪些连接。这是一个服务器还是客户端? - Marcus
12个回答

27

看起来问题是基于服务器端的。

在我的情况下,我与PayPal服务器一起工作,建议的答案都没有帮助,但是http://forums.iis.net/t/1217360.aspx?HTTP+403+Forbidden+error

我遇到了这个问题,刚刚从Paypal技术支持得到了回复。 添加以下内容将解决403错误。 HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.UserAgent = "[任何超过5个字符的单词]";


2
这是我在尝试使用GitHub API时遇到“Forbidden”问题的解决方案。在偶然间发现这篇文章之前,我花了几个小时进行搜索。 - Marc Clifton
1
在生产服务器上,.UserAgent 对我来说是个问题。我猜我必须将IIS设置为禁止没有指定代理的请求。 - secretwep
重复 Spotify ATOM 订阅。 - planetClaire
我也因为从GitHub API收到403而来到这里。后来我发现了这份文档,其中GitHub指出需要UserAgent:https://developer.github.com/v3/#user-agent-required - Bill Menees

24
加入以下一行代码:
request.UseDefaultCredentials = true;

这将允许应用程序使用已登录用户的凭据来访问站点。如果返回403,明显它期望进行身份验证。

还有可能是您(现在?)与远程站点之间存在一个身份验证代理。这种情况下,请尝试:

request.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;

希望这能帮到你。


抱歉耽搁了,我只是在测试。你的第一个建议解决了问题。非常感谢! - user857521

3

这是一个权限错误。你的VS可能是使用管理员账户或不同于安装程序所使用的用户账户运行的。

检查你的IIS权限并查看哪些账户可以访问你正在访问的资源,将其与你使用的账户和已安装版本使用的账户进行交叉参考。


管理员账户在接收请求的Web服务器上是否具有权限?请记住,MyLocalPC\Administrator和server\Administrator不是同一个账户。 - Lotok

2
我们应该使用证书中给定的名称访问网站。 enter image description here

1
在我的情况下,我不得不添加'user agent'和'default credentials=True'。我知道这很老了,但仍然想分享一下。希望能够帮助到大家。以下代码是在powershell中的,但它应该对使用c#的其他人有所帮助。
[System.Net.HttpWebRequest] $req = [System.Net.HttpWebRequest]::Create($uri)
$req.UserAgent = "BlackHole"
$req.UseDefaultCredentials = $true

在我的情况下,我不得不添加以下值,这使它工作起来了: webReq.UseDefaultCredentials = true; webReq.UserAgent = "My API Agent"; webReq.Referer = https://www.example.com; - msola

0
    private class GoogleShortenedURLResponse
    {
        public string id { get; set; }
        public string kind { get; set; }
        public string longUrl { get; set; }
    }

    private class GoogleShortenedURLRequest
    {
        public string longUrl { get; set; }
    }

    public ActionResult Index1()
    {
        return View();
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult ShortenURL(string longurl)
    {
        string googReturnedJson = string.Empty;
        JavaScriptSerializer javascriptSerializer = new JavaScriptSerializer();

        GoogleShortenedURLRequest googSentJson = new GoogleShortenedURLRequest();
        googSentJson.longUrl = longurl;
        string jsonData = javascriptSerializer.Serialize(googSentJson);

        byte[] bytebuffer = Encoding.UTF8.GetBytes(jsonData);

        WebRequest webreq = WebRequest.Create("https://www.googleapis.com/urlshortener/v1/url");
        webreq.Method = WebRequestMethods.Http.Post;
        webreq.ContentLength = bytebuffer.Length;
        webreq.ContentType = "application/json";

        using (Stream stream = webreq.GetRequestStream())
        {
            stream.Write(bytebuffer, 0, bytebuffer.Length);
            stream.Close();
        }

        using (HttpWebResponse webresp = (HttpWebResponse)webreq.GetResponse())
        {
            using (Stream dataStream = webresp.GetResponseStream())
            {
                using (StreamReader reader = new StreamReader(dataStream))
                {
                    googReturnedJson = reader.ReadToEnd();
                }
            }
        }

        //GoogleShortenedURLResponse googUrl = javascriptSerializer.Deserialize<googleshortenedurlresponse>(googReturnedJson);

        //ViewBag.ShortenedUrl = googUrl.id;
        return View();
    }

5
请提供解释,不要仅仅给出答案。这是一大段代码,可能会回答问题,但应配以一些详细说明。 - Cayce K

0

设置:

request.Referer = @"http://www.somesite.com/";

并且添加了适合我的 cookies

你是如何动态添加 cookies 的? - Velkumar

0

这可能对许多人没有太大帮助,但这是我的情况:我正在使用Jira Rest Api,并使用我的个人凭据(我用于登录Jira的凭据)。我已更新了我的Jira密码,但忘记在我的代码中更新它们。我收到了403错误,尝试在代码中更新我的密码,但仍然出现错误。

解决方案:我尝试从他们的登录页面登录Jira,并输入文本以证明我不是机器人。之后,我再次尝试从代码中运行,并成功了。经验教训:服务器可能已将您锁定。


0

刚刚遇到了这个错误。问题是客户端电脑在Windows中的日期/时间设置不正确。


0
在我的情况下,我记得一段时间前为这个地址创建了防火墙的漏洞,因此我必须在配置文件中的绑定上设置useDefaultWebProxy="false",就好像默认情况下如果未指定useDefaultWebProxy,则使用代理。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接