401 when calling Azure website programmatically - c#

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

Related

HttpWebRequest with impersonation

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.

How do I use WebRequest and HttpWebResponse in C# to navigate to an authentication url and login to a website?

I am trying to use the MindMeister API (as documented here: http://www.mindmeister.com/developers/authentication) to make a desktop application. So far, I am able to generate an authentication url as documented on their developer's guide with an api key an shared secret, which ends up looking something like this: http://www.mindmeister.com/services/auth/?api_key=abc123&perms=delete&api_sig=zxy987
If I copy and paste that url into my browser, it takes me to their log in page. Once I log in, then it says my application has been authenticated and I can proceed with my application, which then allows me to start using the different REST API methods. I would like to navigate to that authentication url and login to MindMeister programmatically without having to copy and paste the authentication url into the browser.
So far I have tried something like this
string authenticate
= #"http://www.mindmeister.com/services/auth/?"
+ api_key=abc123&perms=delete&api_sig=zxy987";
WebRequest request = WebRequest.Create(authenticate);
#"https://www.mindmeister.com/account/login");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
//response.ResponseURI == #"https://www.mindmeister.com/account/login"
WebRequest request2 = WebRequest.Create(response.ResponseUri);
request2.Credentials = new NetworkCredential("username", "password");
HttpWebResponse response2 = (HttpWebResponse)request2.GetResponse();
but this does not work.
Can I get some guidance on how to accomplish what I want? I have next to no experience with WebRequest or HttpWebResponse as I basically just copied and pasted other solutions on StackOverflow.
From the documentation it appears that login this way is not officially supported. Keep in mind that most services that operate using an API key can and will revoke this key if they don't like the way it's being used.
However the login might not be needed every time a user starts your application.
It appears that if you get a frob using the mm.auth.getFrob method and pass that as a parameter with the login you could then use that same frob on the mm.auth.getToken method.
You can then store this token somewhere on the users desktop and could use this to use methods in the future.
This should keep working until the user actively revokes the permissions to your application.

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.

How to send a webrequest to default browser from WPF application?

I'm working in a WPF application which is the desktop counter-part of a website.
The idea is that the application should have the same functionalities that the website has, but for the first release of the application not all features would be available, because of this I want to put a link on the features that are not available yet and hopefully when the user click on that link I want to take them to the website, to the page for that functionality.
So far, I can do this with no trouble, using the shell command I can open the default browser and send the request to the resource I need on the website.
Now, the tricky part is that I want to use the credentials that the user used in the desktop application to authenticate with the website, so the user doesn't have to authenticate again, I was thinking in sending the credentials encrypted in a header but I don't know how can I do this, how can I send the header to the web browser from my application.
Any idea on how to do this?
BTW the website is using Forms Authentication.
Thanks.
You could try passing your forms authentication cookie as part of the webrequest.
Uri uri = new Uri("http://services.mysite.com/document/documentservice.svc");
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri);
HttpCookie cookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
Cookie authenticationCookie = new Cookie(FormsAuthentication.FormsCookieName, cookie.Value, cookie.Path, HttpContext.Current.Request.Url.Authority);
webRequest.CookieContainer = new CookieContainer();
webRequest.CookieContainer.Add(authenticationCookie);
WebResponse myResponse = webRequest.GetResponse();
Stream stream = myResponse.GetResponseStream();
try this link

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.

Categories