SOLVED

Project Online/SharePoint Online "401 Unauthorized" error when accessing oData URLs programatically

Copper Contributor

Hi All,

I couldn't authenticate Project Online oData URLs using the below piece of code in a C# console application. It was working fine till yesterday from past 1 year.

SecureString passWord = new SecureString();
foreach (char c in m_Password.ToCharArray()) passWord.AppendChar(c);
var credentials = new SharePointOnlineCredentials("UserName, passWord);
string metaDataURL = "ProjectOnlineURL";
var req = (HttpWebRequest)WebRequest.Create(metaDataURL);
req.Credentials = credentials;

req.Headers["X-FORMS_BASED_AUTH_ACCEPTED"] = "f";
var resp = (HttpWebResponse)req.GetResponse(); //This is where i am getting 401 - Unauthorized error.

Any response is much appreciated ?

Regards,
Sunil G.

14 Replies

Hi Sunil,

 

Something has recently changed and you're not alone in this issue.  It's been slowly rolling out to tenants this week :(   

 

The issue is isolated to the rest apis, so if you can switch your code over to use the CSOM libraries then it will authenticate correctly.

 

  ProjectContext pc = new ProjectContext(url)

 

We have escalated to Microsoft, if we hear of anything I'll update this post.  Please let us know if you hear anything.

 

Thanks

 

Dan

I'm seeing something similar with a REST call in a workflow that creates a subsite. Get a "Forbidden."

 

So it has worked forever, and works on some sites...but not on new ones. 

best response confirmed by Sunil Guntupalli (Copper Contributor)
Solution

Hi All,

 

Another work around is to generate a SharePoint client context and then grab the auth cookie from those credentials and pass it to the rest api request.

 

authCookie = creds.GetAuthenticationCookie()

req.Headers.Add(HttpRequestHeader.Cookie, authCookie);

 

Let me know if you need more details

 

Thanks

 

Dan

I do. I wouldn't know where to start. My workflow is attached. Where would that go?

Daniel,

 

Thank you, i have tried your code and now its working. 

 

Just FYI, here is the piece of updated code i have used.

 

SecureString passWord = new SecureString();
foreach (char c in m_Password.ToCharArray()) passWord.AppendChar(c);
var credentials = new SharePointOnlineCredentials("UserName, passWord);
string metaDataURL = "ProjectOnlineURL";
var req = (HttpWebRequest)WebRequest.Create(metaDataURL);
req.Credentials = credentials;

req.Headers["X-FORMS_BASED_AUTH_ACCEPTED"] = "f";

req.Headers.Add(HttpRequestHeader.Cookie, credentials.GetAuthenticationCookie(new Uri(metaDataURL)));
var resp = (HttpWebResponse)req.GetResponse();

 

Regards,

Sunil G.

Hi Sunil,

 

Glad to hear it worked, thanks for letting me know.  

 

Joe - this is a little more tricky for you given you are calling the api direct in a workflow.  You have a few options on how to fix this but they will all require development and will be a change to your current design. 

 

If this isn't critical to get working I'd sit tight till someone hears back from Microsoft on a ETA in getting the api auth issues resolved.  Given the impact of this issue I'd be hoping to hear something official soon.  

 

 

 

If you have to get this working now and you have access to a developer then you could either create a standalone application that creates the sub sites and leave your workflow alone (benefit here is when MS fixes the issue your workflow will continue to work). 

 

Or you could host your own API wrapper for the SharePoint api in azure that creates the sub sites and update your workflow to use that.  That way in your api you could do the authentication.  This is a pretty big change to your design tho so it might be better to wait.

 

Thanks

 

Dan

 

 

 

Hi Dan,

 

It seems the solution you have suggested is working. But I want to know whether Microsoft is fixing this issue or going forward we need to use different authentication mechanisms

 

Regards,

Mahidhar

Thanks Sunil. Changing the header worked fine.

HI Mahidhar
I'm trying to chase up the same answer with Microsoft ( i dont work for them). Im chatting with their devs so as soon as i hear back ill post it here.

Thanks

Dan

It is curious you mentioned that things are changing. From last weekend to today (9 May 2018) I am also getting the 'The Remote server returned an error: (401) Unauthorized' System.Net.WebException error, where the detail status tells "ProtocolError". The unmodified, proven-tested and working until today CSOM code I tried to run (repeat: always worked fine) with SharePoint Online was:

 

ClientContext context = new ClientContext(serverUrl);

SecureString securestringpassw = new SecureString();
foreach (char c in password) { securestringpassw.AppendChar(c); }

SharePointOnlineCredentials creds = new SharePointOnlineCredentials(username, securestringpassw);

context.Credentials = creds;
context.RequestTimeout = 60000; // ms

Web web = context.Web;

var list = web.Lists.GetByTitle(Library);
context.Load(list.Fields);
context.ExecuteQuery();  // Error 401 here

 

 

I really curious on what is going on... Any clues?

 

Many thanks!

 

But yes, Daniel, your suggestion does work!

Still I am curious on what is going on!

Hi All,

 

I have just received a response from the product team that SharePoint Online no longer sends NTLM challenges on 401 responses. 

 

Their suggestion was to use SPOIDCRL in the request headers.  

 

So continue to authenticate with the sample code I provided earlier which does this.

 

I understand some of you are trying to do this in a SharePoint designer workflow.  I'll try and create one this week and see if there is a way to do this for your workflows.

 

Thanks

 

Dan

Is there no documentation on this change?
1 best response

Accepted Solutions
best response confirmed by Sunil Guntupalli (Copper Contributor)
Solution

Hi All,

 

Another work around is to generate a SharePoint client context and then grab the auth cookie from those credentials and pass it to the rest api request.

 

authCookie = creds.GetAuthenticationCookie()

req.Headers.Add(HttpRequestHeader.Cookie, authCookie);

 

Let me know if you need more details

 

Thanks

 

Dan

View solution in original post