The remote server returned an error: (401) Unauthorized - How can I fix, or do a workaround?

Posted on 2011-10-26
Last Modified: 2012-06-21
I am developing company web site with ASP.NET, where I am using C# to post a question i.e. social content, to a company SharePoint community. The SharePoint site uses NewsGator for social content. This is all happening on a company intranet. The website was developed using VS2008, and the .Net Framework 3.5. The SharePoint site is on a company farm.

When I use the web app from my workstation via the IDE, it works great!, and the question gets successfully posted to the SharePoint Community- Woohoo! But after I publish the web app, to our development environment on a single Windows 2008 R2 server (which resides on a different domain BTW), I’ll use the web app from the server, and when I try to post a question, and I get a error: “The remote server returned an error: (401) Unauthorized.” My code is included as well as the error info.

How can I work around this issue. Keep in mind, I want to do this work around in my code, Doing the workaround on the SharePoint server farm (which is in production) is not an option. Virtually the same applies for the web server, because the app will eventually be on a production web farm.  
    public class ReSTService
       public string HttpPost(string url, string[] paramName, string[] paramVal)
            HttpWebRequest rqst = WebRequest.Create(new Uri(url))as HttpWebRequest;
            rqst.UseDefaultCredentials = true;
            rqst.Method = "POST";
            rqst.ContentType = "application/x-www-form-urlencoded";

            StringBuilder sbParams= new StringBuilder();
            for (int i = 0; i < paramName.Length; i++)

            byte[] formData = UTF8Encoding.UTF8.GetBytes(sbParams.ToString());
            rqst.ContentLength = formData.Length;

            using (Stream post = rqst.GetRequestStream())
                post.Write(formData, 0, formData.Length);

            string result = null;
            using (HttpWebResponse resp = rqst.GetResponse() as HttpWebResponse)
                StreamReader reader = new StreamReader(resp.GetResponseStream());
                result = reader.ReadToEnd();
            return "";

Open in new window

Error Info:
Process information:
    Process ID: 3760
    Process name: w3wp.exe
    Account name: IIS APPPOOL\sswtool
Exception information:
    Exception type: WebException
    Exception message: The remote server returned an error: (401) Unauthorized.
Request information:
    Request URL: httppathhidden/for/thispost/default.aspx
    Request path: /rootDirNameHidden/ssw/default.aspx
    User host address: xx.xx.xx.125
    User: xxx\myID
    Is authenticated: True
    Authentication Type: NTLM
    Thread account name: IIS APPPOOL\rootDirName
Thread information:
    Thread ID: 3
    Thread account name: IIS APPPOOL\rootDirName    Is impersonating: False
    Stack trace:    at System.Net.HttpWebRequest.GetResponse()
   at theNameSpace.ssw.ReSTService.HttpPost(String url, String[] paramName, String[] paramVal) in pathhidden\for\thispost\classes\ReSTService.cs:line 40
   at theNameSpace.ssw.Default.askButton_Click(Object sender, EventArgs e) in pathhidden\for\thispost\classes\Default.aspx.cs:line 47
   at System.Web.UI.WebControls.Button.OnClick(EventArgs e)
   at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
   at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
Question by:mike_wb
    LVL 7

    Expert Comment

    Hi Mike

    I assume you are using IIS 7.5 (Server 2008 R2) 401 indicates authentication problems with either Basic, Digest or Windows Authentication.
     IIS 7.5Please ensure you have the correct Authentication type selected/enabled (example uses windows integrated authentication)
     authenticationAlso ensure that your app pool has the correct settings (found under advanced settings)
     app pool
    My answer is based on a assumption, please advise if I understood it correctly.
    LVL 7

    Expert Comment

    Sorry, i missed the part of changing it in code.

    Author Comment

    No problem Moomin83, thank you, I will take your comment into consideration anyway. If it ends up helping reslove the problem, I will follow up with the info and points
    LVL 8

    Expert Comment

    Do you plan on setting up your web application (the app where your code is running) under a specific user context when it is running?  Because whatever user context your app is running under is going to have to be granted permission to post to the SharePoint site.  It probably works on your dev machine because when you run in debug mode the web app is generally going to run under your user credentials.

    The setup of the user isn't going to be something your application can do unless you build something that allows an admin that has the rights to setup the user to plug in their credentials so that the app can impersonate them in order to setup the accounts.

    Author Comment

    Hi Volox:
    Not sure what you mean by specific user context, would that be like a process ID and pw?  I'll have to google that.

    Do you think the problem might be as simple as this:
    It will work from my workstation because it resides on the same domain, as the domain of the sharepoint site that I have authorized access to, but the the app deployed to the webserver of a different domain, cannot access the the sharepoint site because it is passing the wrong domain in my credentials?

    Or do you think it is more complicated than that?

    LVL 8

    Expert Comment

    It's slightly more complicated than that.  A web application runs under a user context (just like any process has to).  If you don't configure the user under which your web app runs, then it is running as the IIS worker process; that account isn't going to have rights anywhere outside of the machine on which it is running.

    Now as you can see in the screenshots by Moomin83, there is a setting for "Identity" within the IIS setttings.  This can be used to control what user account the website's application pool runs under.  (more explanation here )

    All that being said, if you were to secure your web application so that it is running under Windows Authentication, then your code can impersonate the user that is logged into the site and use those credentials.  However I'm not a super huge fan of this myself do to potential security issues this can create (I'll let you research that religious debate on your own).

    What I would recommend would be to create a user account that you run your website under by configuring the application pool to use that account.  However, if the machine where the web app is deployed isn't in the same domain as the machine that SharePoint is on, then this doesn't work cleanly because you can't provide the same user on both machines.  So knowing your deployment scenario is important in this case.  Can you provide info on the deployment situation?
    LVL 8

    Expert Comment

    Oh, and if your machines aren't in the same domain you will probably need to do something similar to this....

    rqst.UseDefaultCredentials = false;
    rqst.Credentials = new NetworkCredential(username, password);

    Not sure if that's precisely what works with SharePoint because I don't have a SP server to test against right now, but it should head you in the right direction if you can't use the web application identity to solve your issue.

    Of course, then you have the issue of how to store the username and password safely so that they won't be compromised if your web app gets compromised.  (which is why I much prefer the method of setting the user identity of the web app to something that will automatically provide access if that is at all feasible)

    Author Comment

    While I am still gratefully reflecting on and analyzing this information, I can share this much now

    This is a unique/unusual deployment situation, here are some facts:
    1) My workstation where I do my web development is on the prod domain (not unusual)
    2) The server where I deploy the app to test, is on a test domain (not unusual)
    3) The SharePoint sandbox I was provided, resides on the prod domain. (very unusual) - its being called a sandbox, because only a few of us on the project team, have access to the communtiy. It would enventually be available to all authenticated users on the company intranet when its not a sandbox anymore.


    rqst.UseDefaultCredentials = false;
    rqst.Credentials = new NetworkCredential(username, password,domain);

    I added the above code, deployed to and ran from the test server, and it worked with sharepoint like I wanted. Of course we don't want to it this way, but I hope it provides a clue.

    GTG: more info to come
    Thank You
    LVL 8

    Accepted Solution

    That definitely helps.

    Does your test domain trust your prod domain?  In other words, can you use credentials from the prod domain to assign rights to things in the test domain?  If so, then you can still run your app in the test domain under a prod account.  If not, then you're kind of stuck with a test environment that is going to have to work differently than your prod domain.

    If that's the case, what you might do is this... you might build your app so that it looks for a setting in the config to tell it to pull the username and password information out of the config.  If the setting isn't present or is set to not pull from config, then you use the default credentials.  This would allow you to use a specific set of crendtials when you run the application in test and use the method of setting up the website under a specific account when you are in prod.

    Author Closing Comment

    All of your info was helpfull, For now at least have now have a work around for demonstration purposes. Thank You

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    IT, Stop Being Called Into Every Meeting

    Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

    Suggested Solutions

    Just a quick little trick I learned recently.  Now that I'm using jQuery with abandon in my applications, I have grown tired of the following syntax:      (CODE) I suppose it just offends my sense of decency to put inline VBScript on a…
    Problem Hi all,    While many today have fast Internet connection, there are many still who do not, or are connecting through devices with a slower connect, so light web pages and fast load times are still popular.    If your ASP.NET page …
    Need more eyes on your posted question? Go ahead and follow the quick steps in this video to learn how to Request Attention to your question. *Log into your Experts Exchange account *Find the question you want to Request Attention for *Go to the e…
    Sending a Secure fax is easy with eFax Corporate ( First, Just open a new email message.  In the To field, type your recipient's fax number You can even send a secure international fax — just include t…

    779 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    15 Experts available now in Live!

    Get 1:1 Help Now