HttpWebRequest with impersonation - c#

I am working on an application in an environment where users have NTLM, single-sign-on authentication for all applications. Basically, the applications open and they are recognized by gathering information from the user's profile. The application I am working on is an extension to an existing Web Application. This application uses impersonations with an existing service account in Active Directory. Now, inside my application I do a System.Net.HttpWebRequest to a second server that is running a data service. When I place the request I do this:
System.Net.HttpWebRequest request = System.Net.WebRequest.Create(URL) as System.Net.HttpWebRequest;
request.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
request.Method = "Get";
using (System.Net.HttpWebResponse response = request.GetResponse() as System.Net.HttpWebResponse)
{ ...
As you can see I set the credentials to DefaultNetworkCredentials to make sure that whoever is logged the credentials will be passed in the request. It works well when I tried from the VM hosting my the application. So, if I place the request to my application inside the hosting VM as http://localhost/myapplication it all works fine. However, when I call the same application from outside the VM with the explicit server name as in http://myservername/myapplication, then the secondary server I am requesting the data from rejects the call with a 401 Unauthorized error.
Any ideas? How can I trace what is happening? I tried Fiddler and I do not see anything going on.
Thanks in advance!
UDPATE: I changed the account the application pool runs on to an admin user. I got the same result.

Related

401 when calling Azure website programmatically

I have an Azure website running with active directory enabled. I am able to log in to the website just fine with various accounts by going through the Azure login page.
I get a 401 when attempting to call an API on that website from a .net client with any account I try.
var request = WebRequest.Create(url);
request.Method = "GET";
request.Credentials = new NetworkCredential("username#ourdomain.com", "password");
request.GetResponse();
Is there a way to hit the website without going through the actual azure login page?
You're going to have to use an Azure Active Directory Authentication Library (ADAL). See https://msdn.microsoft.com/en-us/library/azure/dn151135.aspx
See for example the code samples on Web Application to Web API. This one looks like it would be useful for your application: https://github.com/AzureADSamples/WebApp-WebAPI-OAuth2-UserIdentity-Dotnet

Asp.net forms authenticated webservice

I have a small conundrum where I have an asp.net application that's using forms based authentication. Inside of the application, I have a webservice that checks User.IsInRole("somerole") which works fine with ajax calls from the application since the user is logged in, and the ajax calls come from his logged in browser.
Now, I want to make a fat client call the webservices (c# console client for starters), but cant figure out how to pass the credential information to it.
I've looked at doing something like the following to no avail:
SomeWebService svc = new SomeWebService();
svc.Credentials = new NetworkCredential("formsusername","formspassword","");
String returnValue = svc.CallMyWebMethod();
Can anyone out there show me the trick to this? :-)
Thanks!
Forms Authentication works by having the client send a Cookie along each request. This cookie is emitted by the server when the client successfully authenticates by sending the correct credentials.
So here are the steps that you need to do in your console application in order to authenticate the user using forms authentication:
Send an HTTP POST request to some web page passing the username and password. In response the web server will give you the authentication cookie (Set-Cookie HTTP response header) that you need to capture. That's usually your Log page.
When calling your web service you need to pass this cookie (Cookie HTTP request header). In order to set a cookie along with the request, you will have to override the GetWebRequest method on the client proxy class that was generated for you:
protected override WebRequest GetWebRequest(Uri uri)
{
var request = (HttpWebRequest)base.GetWebRequest(uri);
request.CookieContainer.Add(
new Cookie(
".ASPXAUTH",
"THE VALUE YOU HAVE RETRIEVED WHEN YOU SEND YOUR FIRST LOGON REQUEST"
)
);
return request;
}

Infopath COM object authentication failure using Web Service

So I have a windows forms application that loads an infopath form(.xml) from a sharepoint library, and does some processing to it. I created an exe out of it and I just supply a sharepoint library url to it through cmd and it pulls up the form.
I also have a web service which runs on an IIS server that calls the exe and displays infomartion for specific users. Now the problem is when I call the exe from then web service, it kept on asking for a login prompt. So i figured the web service must be running as a System account, and i supplied credentals through a number of ways
WebRequest request = WebRequest.Create(sharepoint_url);
request.Credentials = CredentialCache.DefaultNetworkCredentials;
or
request.Credentials = new NetworkCredential("","");
I also tried System.Net.CredentialCache mycache = new System.Net.CredentialCache();
mycache.Add(formUrlName, "Basic", new System.Net.NetworkCredential("", "")); and
request.Credentials = mycache;
But all the time i got an exception being thrown....Infopath cannot open this frm...the signature on this form is not from a trusted publisher.
Then I tried loading my project along with the web service and creating a new form ( Form form2 = new Form()), but doing the authentication procedure first. Now I get a http 401 unauthorized error.
(I use FormControl.Open(url) to open the form fromm the sharepoint library)
What am i doing wrong?
UPDATE:
I checked with the admin of the sharepoint library...apparently, the credentials are not being received at all. I dont know if they are not being sent properly or whether sharepoint is just dropping the credentials and not accepting it.

Proxy Authentication Issues

I manage an internal SharePoint portal (Moss 2007) that has webparts, some of which fetch RSS feeds from yahoo news, while others from yahoo finance (daily stock market charts), yet another one with current weather from NOAA. All of these work except yahoo news. The error I get is:
The remote server returned an error: (407) Proxy Authentication Required.
However, if I run the code locally on my dev box (Win 7) (VS2010) as a web app, the new feed works fine. I understand that this an authentication issue but I can't get any help from our IT security folks.
The difference between the server and my workstation is that I login with a magnetic card and authenticate against the domain. The browser my PC uses goes through a proxy that has some exceptions listed including the SharePoint portal. Bypass proxy for local addresses is checked. The sever itself is locked down from any direct (or via proxy) internet access so the authentication requests have to be coded.
I didn't write this code, but it works fine on one server but will not on my SharePoint server. I have diligently compared setting and found that on a server where it is used as a web widget, it works fine. The web site uses impersonation using a domain account. If I use impersonation in SharePoint, I get logged in with the impersonation account, rather than with my credentials. Are you still with me?
So this code gets the proxy server info fed in but without the any credentials info:
WebRequest myRequest = WebRequest.Create(rssURL);
string[] arrProxy = System.Configuration.ConfigurationManager.AppSettings["ProxyServer"].Split(new Char[] { ',' });
myRequest.Proxy = new System.Net.WebProxy(arrProxy[0], Convert.ToInt32(arrProxy[1]));
WebResponse myResponse = myRequest.GetResponse();
Stream rssStream = myResponse.GetResponseStream();
XmlDocument rssDoc = new XmlDocument();
rssDoc.Load(rssStream);
XmlNodeList rssItems = rssDoc.SelectNodes("rss/channel/item");
Can you set the Credentials on the request:
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
request.Credentials = new NetworkCredential("username", "password", "domain");
I guess either with your account, or get the IT guys to create a special "server-webaccess" account.

Why do I get a 401 Unauthorized when making a HttpWebRequest with the correct credentials?

I have a url and a username and password to an external site.
If I access the URL through a browser, an authentication box pops up. I give it the username and password, and I can get to the page.
I am trying to achieve the same thing through code, using a HttpWebRequest object:
var webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.GetResponse() etc…
This used to work before the web sites owners added some protection to the site, and provided me with the username and password.
The WebRequest has a credentials property, which I have been setting as follows:
webRequest.Credentials = new NetworkCredential("username", "password")
I have also tried:
webRequest.Credentials = new NetworkCredential("username", "password", “url domain”)
this always result in the error:
“The remote server returned an error: (401) Unauthorized.”
Am I missing something obvious?
Using System.Net.NetworkCredential might not be effective depending on the authentication model of the resource. It would be helpful to understand the model used by the remote site.
OpenID, Forms Authentication, and Integrated Windows Authentication all work differently. You can attempt to deduce what authentication method they use using tools as #Christoph and #Lex describe, or simply contact the remote web site provider.
If the remote site uses a negotiating protocol, such as Kerberos or NTLM, then the behavior you are experiencing is strange, indeed; however, some other protocols may require you to go about it another way.
If you use HTTP, please simply use Microsoft Network Monitor or Wireshark to capture what kind of 401 message is returned from the web server. It can be 401.3 or another error code which has in fact another meaning.
If there is no privacy concern, you may wish to post the url you are trying to access.
If the URL is malformed, or references an invalid page (or an invalid page + parameters combination) you will sometimes see server errors like this.
I worked with a legacy web app from the state of Michigan and it would throw 400 style errors every time I tried to access a page with the wrong page parameters.
Are you using request filtering on the web server? Can you check the different verbs which are setup to be denied?
try to debug your request with fiddler (www.fiddler2.com).
Therefore you must start Fiddler, and add the Proxy Settings to your Request:
webRequest.Proxy = New WebProxy("http://127.0.0.1:8888")

Categories