401 Unauthorized uploading to Sharepoint 2013 - c#

I am tring to use the .Net WebClient object to PUT a file to a sharepoint library using basic authentication, it works in sharepoint 2010 in classic mode but does not work in Sharepoint 2013 in Claims mode.
public static void UploadFile(string remoteFileURL, byte[] file)
{
WebClient webclient = new WebClient();
webclient.Credentials = new NetworkCredential("username", "password", "domain");
webclient.UploadData(remoteFileURL, "PUT", file);
webclient.Dispose();
}

The 401 Unauthorized error is an HTTP status code that means the page you were trying to access can not be loaded until you first log on with a valid user ID and password.
If you received the 401 Unauthorized error, it means that the credentials you entered were invalid for some reason.
In your case you are making a put request. On a browser 401 prompts you to input valid credentials until you click on cancel.
Considering that it worked on SharePoint 2010, these could be the possible errors : -
The credentials you are using are not valid in the SharePoint 2013 server
SharePoint 2013 server is configured to disable pull requests
The user you are trying use does not have access privileges to perform a pull request
From my search on claims mode, I found out that there is a setup which involves adding/migrating users in claims mode which uses a different form of authentication. I think this might be your issue and you should try to check the validity of credentials and access privileges of user you are working with.

Could be a number of dependencies:
Does the account have access?
Is WebDav a contingency?
Maybe this link might help, but it requires CSOM C#

Related

Error 400: redirect_uri_mismatch when using gmail api (.net)

Ok, so I'm trying to implement Gmail API on this project, everything I want to do is send an email, this is what I got so far:
Register a new project at google developers console, enable the gmail API and configure the consent screen.
In consent screen I just changed app name and scopes for gmail.send.
Create my credentials as a webapp and this what I put on redirect uris.
http://localhost/Home/Index
As I'm working with MVC and wanted to use the template with Home controller and Index View, I don't know if this is correct but as far as I know, I must write the page where it should go after the authentication and that's the only page in my project.
Then I download the credentials.json file and add it to my project, then execute this code, ruta is the path to my credentials.json
UserCredential credential;
using (var stream =
new FileStream(ruta, FileMode.Open, FileAccess.Read))
{
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None).Result;
}
After that I execute the program but I never see the auth page, instead of that, comes the error:
Error 400: redirect_uri_mismatch. The redirect URI in the request, http://127.0.0.1:62297/authorize/, does not match the ones authorized for the OAuth client.
I've tried to add that URI as "http://localhost/authorize" and "http://localhost/authorize/" to my redirect URIs but I keep getting the same error message.
I'm pretty newbie with this, so I'm a bit lost about all this redirect uris, thanks for your answers
The redirect uri in google developer console must exactly match the one you are sending from. It basically tells Google's authorization server where you would like the
Error 400: redirect_uri_mismatch. The redirect URI in the request, http://127.0.0.1:62297/authorize/, does not match the ones authorized for the OAuth client.
Means that you are sending from http://127.0.0.1:62297/authorize/ and have not added this Port in your google developer console for that project. credentials returned to.
Video showing how to fix this: How the fix redirect_uri_mismatch error. Part 2
static port needed.
If the port number is changing this is an issue with your development environment on your project you need to set the project up to use a static port that you can add to Google developer console.
MVC vs installed application
You state in your question that you are using MVC how ever the code you are using GoogleWebAuthorizationBroker.AuthorizeAsync is designed to work with installed applications. When it runs it will launch the consent window browser on the machine that its running off. THis will not work with a web application as it will attempt to launch a browser on the server which it doesnot have access to do.
Instead use GoogleAuthorizationCodeFlow
Here is example that work for me. Authorised JavaScript origins: 127.0.0.1 Authorised redirect URIs: 127.0.0.1/oauth/complete/google-oauth2 We should not use any port number after main url. Remove the port number. That's all.
Go here & correct the redirect urls: `
https://console.cloud.google.com/apis/credentials/oauthclient/
`

Using default credentials to call api in console app

I'm trying to call a Web API 2 method that requires auth from a console app running on my desktop where I have authorization, but I'm getting 401 Unathorized. I know I have authorization because when I make the same call from a web browser it works fine. So a browser can get my default login id/pw to send to the API but .NET's WebClient can't? That seems insane. There has to be a way to do this without entering my id/pw into the console app.
The below is what I'm using in a console app and it's not working.
This is using Windows Auth as it's intranet stuff.
This throws an exception "The remote server returned an error: (401) Unauthorized."
using(var c = new WebClient())
{
c.UseDefaultCredentials = true;
string value = c.DownloadString("http://localhost:62659/api/Store/GetData");
}
I also tried the below and when I mouse over DefaultNetworkCredentials the username/pw are blank strings. Why wouldn't .NET be able to figure this out?
using(var c = new WebClient())
{
var creds = new CredentialCache();
var uri = new Uri("http://localhost:62659/api/Store/GetData");
creds.Add(uri, "ntlm", System.Net.CredentialCache.DefaultNetworkCredentials);
c.Credentials = creds;
string value = c.DownloadString(uri);
}
It is likely that you do not have your credential information stored within Windows Credential Manager. You can access that via Control Panel > Credential Manager. From there you can add whatever credential you need. CredentialCache.DefaultCredentials and CredentialCache.DefaultNetworkCredentials contains the login credentials of the currently logged-in or impersonated user. If what you are connecting to requires different credentials then these will not work. You will need to add those credentials to the Credential Manager in Windows.
The reason you are connecting fine within Chrome is that Chrome will store credentials within itself that you have designated to save.
Login credentials being used as functional ids can be set to never expire, or it will need to be added to a list of monthly/yearly maintenance items to update the password for those accounts.
You would also want to handle bad login information within your application. If this is an automated task, have it email or otherwise notify someone that the credentials need to be updated.
If a user runs this, you could simply prompt the current user to provide a new password, which you can use to update the stored credentials right then.
Another option would be to set the user running the application as a user on the receiving end using those same credentials. That way the entire process is tied to the user(s) that will be running the application.
Using DefaultCredentials should work to use Windows Auth from console application. As long as you have the appropriate authorization header that your web api is looking for. Same with my comment I recommend testing the api call using Postman so that you can troubleshoot and check what you are missing.
Regarding the credentials as blank, this is maybe because you are using DefaultNetworkCredentials.
Try this:
using(var c = new WebClient())
{
var uri = new Uri("http://localhost:62659/api/Store/GetData");
c.Credentials = System.Net.CredentialCache.DefaultCredentials;
string value = c.DownloadString(uri);
}
If you want to use NetworkCredential you should be inputting network credentials like so:
c.Credentials = new NetworkCredential(username, password, domain);
I created this type of console application and used it as a service and I can tell you that this should work. You should just need to troubleshoot and bits by bits get the real problem.

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