Sharepoint REST API via app-only principal suddenly stopped working - oauth-2.0

We are using the Sharepoint Rest API to index contents.
Due to a customer's security requirement, we can only use API permissions as granted in the Sharepoint Admin Center in combination with an app-only principal with a secret.
We registered an application in the Azure AD Admin Center and granted it permissions as described here.
We then wrote a piece of Java Code that adapts the requests described here to retrieve a JWT:
List<NameValuePair> params = new ArrayList<>(10);
params.add(new BasicNameValuePair("grant_type", "client_credentials"));
params.add(new BasicNameValuePair("client_id", clientId + "#" + directoryId));
params.add(new BasicNameValuePair("client_secret", clientSecret));
params.add(new BasicNameValuePair("resource", "00000003-0000-0ff1-ce00-000000000000/" + targetHost + "#" + directoryId));
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
HttpPost post = new HttpPost("https://accounts.accesscontrol.windows.net/" + directoryId + "/tokens/OAuth/2");
post.setEntity(new UrlEncodedFormEntity(params, Consts.UTF_8));
String result;
try (CloseableHttpResponse response = httpClient.execute(post)) {
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK)
throw new SharepointClient.HttpStatusException(response.getStatusLine().getStatusCode());
result = Strings.fromUtf8(IO.readAll(response.getEntity().getContent()));
}
accessToken = new JsonData(result).get("access_token");
}
We then use the token as a bearer token in the authorization header for all requests to the API.
This worked fine for a couple of months until about a week ago. Since then, we're only receiving 403 responses.
HttpResponseProxy{HTTP/1.1 403 Forbidden [Cache-Control: private, max-age=0, Transfer-Encoding: chunked, Content-Type: application/json;odata=verbose;charset=utf-8, Expires: Wed, 30 Sep 2020 09:58:49 GMT, Last-Modified: Thu, 15 Oct 2020 09:58:49 GMT, P3P: CP="ALL IND DSP COR ADM CONo CUR CUSo IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI", X-SharePointHealthScore: 2, X-MSDAVEXT_Error: 917656; Zugriff+verweigert.+Zum+%c3%96ffnen+von+Dateien+an+diesem+Speicherort+m%c3%bcssen+Sie+zun%c3%a4chst+zur+Website+wechseln+und+die+Option+zur+automatischen+Anmeldung+aktivieren., DATASERVICEVERSION: 3.0, X-AspNet-Version: 4.0.30319, SPRequestGuid: f7dd839f-10d1-2000-73fa-40c47dd29bbb, request-id: f7dd839f-10d1-2000-73fa-40c47dd29bbb, MS-CV: n4Pd99EQACBz+kDEfdKbuw.0, Strict-Transport-Security: max-age=31536000, X-FRAME-OPTIONS: SAMEORIGIN, Content-Security-Policy: frame-ancestors 'self' teams.microsoft.com *.teams.microsoft.com *.skype.com *.teams.microsoft.us local.teams.office.com *.powerapps.com *.yammer.com *.officeapps.live.com *.stream.azure-test.net *.microsoftstream.com;, X-Powered-By: ASP.NET, MicrosoftSharePointTeamServices: 16.0.0.20530, X-Content-Type-Options: nosniff, X-MS-InvokeApp: 1; RequireReadOnly, X-MSEdge-Ref: Ref A: 330CB0BA15E647CC8B732FCC45D4F950 Ref B: AM3EDGE0620 Ref C: 2020-10-15T09:58:49Z, Date: Thu, 15 Oct 2020 09:58:49 GMT] ResponseEntityProxy{[Content-Type: application/json;odata=verbose;charset=utf-8,Chunked: true]}}
The error message is in german (I don't know why, the whole system is set to english). It sais: "Access denied. To open files in this location, you have to first go to the website and activate the option for automatic login."
Does anyone know what might have changed? Do we need to change something in the requests?
We already checked:
The secret is not expired
Authentication via certificate and Azure AD Admin Center permissions is still working (same API requests, just the token retrieval is done with msal4j)
Sending the token request and the API requests via Postman leads to the same results

The reason for the error is not that you lack permissions. According to the error message Access denied. To open files in this location, you have to first go to the website and activate the option for automatic login.
Do you need:
1.Authenticate to Office 365.
2.Add your SharePoint Online sites to trusted sites.
3.Check the status of the WebClient service.
see: Troubleshoot mapped network drives that connect to SharePoint Online.

Related

Microsoft Teams: Owners cannot create additional Apps after being added via ms graph

We have the following bug in Microsoft Teams:
Owners added via the Graph API to a newly created group cannot create additional APPs like Planner in Microsoft Teams.
We use the following graph endpoint to add owners to the group after the group has been created. The graph call is authentificated using an azure ad service principal (azure ad application) using a certificate.
https://developer.microsoft.com/en-us/graph/docs/api-reference/beta/api/group_post_owners
The owners are added approximately 20 minutes after creation of the group as stated in this article (Wait for 15 minutes + 5 Minutes PNP Template):
https://developer.microsoft.com/en-us/graph/docs/api-reference/beta/api/team_put_teams
If the group was created less than 15 minutes ago, it's possible for
the Create team call to fail with a 404 error code due to replication
delays. The recommended pattern is to retry the Create team call three
times, with a 10 second delay between calls.
The problem doesn't occur anymore if the user is completely deleted from owers of the group and then added again via the frontend (no matter if SharePoint, Teams or Outlook).
We can reproduce the problem at any time.
Error message
The following error occurs when a plan is to be created via the group:
e2141e79-10fe-4bcc-91dc-ff1990ad86f7
Date and Time: 05.11.2018
08:34:46 Planner Version: 16.0.11026.35000
Additional Data:
TenantId:
1ca8bd94-3c97-4fc6-8955-bad266b43f0b
OwnerId:
1ca8bd94-3c97-4fc6-8955-bad266b43f0b
GroupId:
25fcf2d5-cecc-44b0-bd03-d6719389e446
Response Headers:
cache-control:
private, s-maxage=0
content-length:
1233
content-security-policy:
frame-ancestors 'none';
content-type:
text/html
date:
Tue, 06 Nov 2018 08:28:15 GMT
p3p:
CP="CAO DSP COR ADMa DEV CONi TELi CUR PSA PSD TAI IVDi OUR SAMi BUS DEM NAV STA UNI COM INT PHY ONL FIN PUR"
status:
403
strict-transport-security:
max-age=31536000; includeSubDomains
x-aspnet-version:
4.0.30319
x-aspnetmvc-version:
5.1
x-content-type-options:
nosniff
x-correlationid:
aeaf0deb-4cab-4c67-a406-6ec6eb527ad0
x-frame-options:
Deny
x-msedge-ref:
Ref A: 368E038C7FA5468CA7805EB1C708B607 Ref B: AMS04EDGE0210 Ref C: 2018-11-06T08:28:15Z
x-officecluster:
neu-000.tasks.osi.office.net
x-officefe:
TodoFrontEndBox_IN_6
x-officeversion:
16.0.11026.35000
x-powered-by:
ASP.NET
x-proxycluster:
neu-000.tasks.osi.office.net
x-proxyfe:
TodoFrontEndBox_IN_6
x-proxyversion:
16.0.11026.35000
x-usersessionid:
ece4e392-c1a8-4498-ae8d-aaf8ef99cf27
I'm guessing you're an owner but not a member. Planner doesn't support that -- add yourself to the members collection as well.

Microsoft Graph API Download File content return Unauthorized 401

I'm trying to download a file from SharePoint Online using an "app only" token. I can obtain file info using this url
https://graph.microsoft.com:443/v1.0/sites/{siteId}/drives/{driveId}/list/items/{itemId}/driveItem
But when I try to download the file with this url
https://graph.microsoft.com:443/v1.0/sites/{siteId}/drives/{driveId}/list/items/{itemId}/driveItem/content
I get the following error
403 FORBIDDEN
Content-Length →13
Content-Type →text/plain; charset=utf-8
Date →Fri, 13 Apr 2018 08:47:12 GMT
MicrosoftSharePointTeamServices →16.0.0.7604
P3P →CP="ALL IND DSP COR ADM CONo CUR CUSo IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI"
SPIisLatency →2
SPRequestDuration →53
X-Content-Type-Options →nosniff
X-MS-InvokeApp →1; RequireReadOnly
X-MSDAVEXT_Error →917656; Access+denied.+Before+opening+files+in+this+location%2c+you+must+first+browse+to+the+web+site+and+select+the+option+to+login+automatically.
X-MSEdge-Ref →Ref A: B9E0C567B0CC4E60AEE93EEB8DC06AF1 Ref B: VIEEDGE0813 Ref C: 2018-04-13T08:47:12Z
X-Powered-By →ASP.NET
X-SharePointHealthScore →0
what is wrong?
it seems that internally it generates a download link (.../_layouts/15/download.aspx?UniqueId=...) that works with username / pwd token, but does not work with "app only" token
I have another office 365 subscription that works with "app only" token. The other subscription have a custom domain, but I can not see other configuration differences (both have LegacyAuthProtocolsEnabled property set to true, same sharing options...)
EDIT: It seems that the example I was testing on friday now works!!
This bug appeared wednesday last week, and is spreading to more and more of our tenants. It appears that temporary tokens generated by the Graph API/Sharepoint API are invalid. This affects:
Chunked file upload, as you receice an url to upload to with a temporary token
#microsoft.graph.downloadUrl as it contains a temporary token
Content download, as it uses the excact same url as #microsoft.graph.downloadUrl
Please fix this ASAP, as my application is cripled and the customers are angry
I created a post here too, but no response: Temporary tokens issued by graph api is invalid since wednesday
Also this bug appeared wednesday: Unable to set fileSystemInfo.lastModifiedDateTime on files on Sharepoint Online for some users since wednesday
Did you find anything on this Mark LeFleur?
You should use the #microsoft.graph.downloadUrl property obtained from the /v1.0/me/drive/list/items/x/driveItem response to get an app-only url to the file.
A GET request wil allow you to download the file.
See https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/resources/driveitem#instance-attributes
I have executed the same example that initially failed and now works, at least in the two tenants that I have.
I have not changed any configuration or source code, so it seems that it was a temporary problem that has been fixed.

Desire2Learn Valence API non-interactive authentication

In the Desire2Learn Valence API, is there a non-interactive authentication flow for server applications? The Valence documentation appears to assume that any authenticating application will be an interactive client process.
We actually accomplished this by non-interactively logging into the site.
If you try this route, make sure to grab the d2lSecureSessionVal, d2lSessionVal, and Login cookies and add them to your subsequent requests.
Request 1:
1 > POST http{s}://elearning.test.masked.edu/d2l/lp/auth/login/login.d2l
1 > Content-Type: application/x-www-form-urlencoded
userName={Your Username}&password={Your Password}
Response 1:
1 < Set-Cookie: LoginKey=; expires=Sat, 01-Jan-2000 05:00:00 GMT; path=/
1 < Set-Cookie: d2lSecureSessionVal=masked; path=/; HttpOnly <-- grab this
1 < Set-Cookie: Login=true; path=/ <-- grab this
1 < Set-Cookie: d2lSessionVal=masked; path=/ <-- grab this
Note that on this request, the target doesn't really matter much
Request 2:
2 > GET http{s}://elearning.test.masked.edu:443/d2l/auth/api/token?x_a=ZNsxGYZuSmasked&x_b=7jkhCKfEmaked&x_target=https%3A%2F%2Fwww.maked.edu
2 > Cookie: d2lSecureSessionVal=masked; d2lSessionVal=masked; Login=true;
It will try to redirect you to the target site. Ignore the redirect, x_a is what you are really after.
Response 2:
2 < 302
2 < X-AspNet-Version: 2.0.50727
2 < Date: Tue, 09 Oct 2012 14:03:45 GMT
2 < Content-Length: 248
2 < X-XSS-Protection: 0
2 < Location: http{s}://www.masked.edu?x_a=DxHmasked&x_b=aQVkg-7jkhCKfEmaked&x_c=IfLBcKYFf8masked
2 < Set-Cookie: TS50cdf6=masked; Path=/
2 < Content-Type: text/html; charset=utf-8
2 < X-Powered-By: ASP.NET
2 < Cache-Control: private
2 <
Grab x_a from this response and use it as x_b in your requests
The first time is a bugger since there is a page that displays a check box to allow requests from a specific host. We just grabbed the auth token request and popped it in a browser. After checking the box to always allow, things work just fine.
Note also that the auth token will expire occasionally. Make sure you code for that and re-authenticate when it happens.
I used the getting started example code from the PHP example code, which shows you the userkeys in your browser after you log in, to get the keys for my "service account" that I created.
I then put these into a PHP class that I could reuse to make connections. So in my code, I can call
$authcontext = d2l::connect();
It really works like a charm.
This is somewhat connected to the question located here:
Authenticaton Method for Desire2Learn REST API vs SOAP
Valence APIs do require that an interactive auth step has occurred, but, this can be done at "install time" for a non-interactive app. The result of that process are keys that can be used "for a long time".
For some version and service pack levels this was 30 days, but, can be made to "not expire". "Not expire" is the expected default going forward, but, if it is still set to 30 days on your instance you can make a support request to have it change.

Google OAuthGetRequestToken returns "signature_invalid"

Trying for hours to get a request token using Google OAuthGetRequestToken but it always returns "signature_invalid".
For a test I use the oAuth Playground to successfully request the token. Here are the results:
Signature base string
GET&https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthGetRequestToken&oauth_callback%3Dhttp%253A%252F%252Fgooglecodesamples.com%252Foauth_playground%252Findex.php%26oauth_consumer_key%3Dwww.embeddedanalytics.com%26oauth_nonce%3D56aa884162ed21815a0406725c79cf79%26oauth_signature_method%3DRSA-SHA1%26oauth_timestamp%3D1321417095%26oauth_version%3D1.0%26scope%3Dhttps%253A%252F%252Fwww.google.com%252Fanalytics%252Ffeeds%252F
Request/Response
GET /accounts/OAuthGetRequestToken?scope=https%3A%2F%2Fwww.google.com%2Fanalytics%2Ffeeds%2F HTTP/1.1
Host: www.google.com
Accept: */*
Authorization: OAuth oauth_version="1.0", oauth_nonce="56aa884162ed21815a0406725c79cf79", oauth_timestamp="1321417095", oauth_consumer_key="www.embeddedanalytics.com", oauth_callback="http%3A%2F%2Fgooglecodesamples.com%2Foauth_playground%2Findex.php", oauth_signature_method="RSA-SHA1", oauth_signature="qRtorIaSFaQdOXW1u6eMQlY9LT2j7ThG5kgkcD6rDcW4MIvzluslFgYRNTuRvnaruraNpItjojtgsrK9deYRKoHBGOlU27SsWy6jECxKczcSECl3cVAcjk7dvbywFMDkgi1ZhTZ5Q%2BFoD60HoVQUYnGUbOO0jPXI48LfkiA5ZN4%3D"
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Date: Wed, 16 Nov 2011 04:18:15 GMT
Expires: Wed, 16 Nov 2011 04:18:15 GMT
Cache-Control: private, max-age=0
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Content-Length: 118
Server: GSE
oauth_token=4%2FmO86qZzixayI2NoUc-hewC--D53R&oauth_token_secret=r0PReF9D83w1d6uP0nyQQm9c&oauth_callback_confirmed=true
I am using Fiddler to trace my calls. It returns the Signature base string:
GET&https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthGetRequestToken&oauth_callback%3Dhttp%253A%252F%252Fgooglecodesamples.com%252Foauth_playground%252Findex.php%26oauth_consumer_key%3Dwww.embeddedanalytics.com%26oauth_nonce%3Dl9Jydzjyzt2fJfM3ltY5yrxxYy2uh1U7%26oauth_signature_method%3DRSA-SHA1%26oauth_timestamp%3D1321417107%26oauth_version%3D1.0%26scope%3Dhttps%253A%252F%252Fwww.google.com%252Fanalytics%252Ffeeds%252F
Aside from the oauth_timestamp and oauth_nonce (which should be different), the base string are pretty much identical.
Anyone know what I am doing wrong?
Update 11/20/2011 Thinking it might be something wrong with my RSA-SHA signing, I have since tried HMAC-SHA. It gives the same results. I thought it might be beneficial to include the Fiddler results (I added carriage returns to have it format better).
GET https://www.google.com/accounts/OAuthGetRequestToken?
scope=https%3A%2F%2Fwww.google.com%2Fanalytics%2Ffeeds%2F HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Authorization: OAuth oauth_version="1.0",
oauth_nonce="7C4C900EAACC9C7B62E399A91B81D8DC",
oauth_timestamp="1321845418",
oauth_consumer_key="www.embeddedanalytics.com",
oauth_signature_method="HMAC-SHA1",
oauth_signature="ows%2BbFTNSR8jVZo53rGBB8%2BfwFM%3D"
Host: www.google.com
Accept: */*
Accept-Encoding: identity
Response
HTTP/1.1 400 Bad Request
Content-Type: text/plain; charset=UTF-8
Date: Mon, 21 Nov 2011 03:16:57 GMT
Expires: Mon, 21 Nov 2011 03:16:57 GMT
Cache-Control: private, max-age=0
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Content-Length: 358
Server: GSE
signature_invalid
base_string:GET&https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthGetRequestToken
&oauth_consumer_key%3Dwww.embeddedanalytics.com
%26oauth_nonce%3D7C4C900EAACC9C7B62E399A91B81D8DC
%26oauth_signature_method%3DHMAC-SHA1
%26oauth_timestamp%3D1321845418
%26oauth_version%3D1.0
%26scope%3Dhttps%253A%252F%252Fwww.google.com%252Fanalytics%252Ffeeds%252F
Update 11/24/2011 - I want to add more information based on the answers from #Meysam and #Bob Aman. First, my domain is properly registered with Google. I have been using AuthSub for quite some time now with Target URL path prefix set to http://www.embeddedanalytics.com/authsubsuccess.html. Now when I go to the Manage Domains section it states my oAuth consumer key is www.embeddedanalytics.com. Now perhaps this could be a problem. In the Registration for Web-Based Applications document it states:
If you're using the OAuth interface, this URL (the "Target URL path prefix") must match the value of the oauth_consumer_key parameter
In my case I have a target URL different from my oauth_consumer_key. Could this be a problem? I use www.embeddedanalytics.com as the consumer_key in the playground and it works. I don't want to mess with the target URL because it is currently being used with my AuthSub authorizations.
I assume you have not registered your application domain with Google. Therefore, whatever consumer secret you are using to sign your request (in HMAC-SHA1 method) will be denied unless you provide anonymous as your oauth_consumer_key and consumer secret. This way, Google will recognize you as an unregistered application and will successfully return you a Request Token.
If you use the HMAC-SHA1 method, the Consumer Secret and Token Secret will be used to sign your requests. These two secret parameters are known both to your application, and Google, and act like a secret key in a symmetric encryption algorithm.
In order to use RSA-SHA1 method however, you should have already uploaded your Public Key to the server (Google Server) during the registration process of your application. After that, you will use your Private Key to sign your OAuth requests. In your case, since you have not registered your application, Google is not aware of your Public Key, and therefore using RSA-SHA1 method to sign your requests with an unknown Private Key is of no use.
The first method is usually preferred over the RSA-SHA1 method for performance reasons. (symmetric encryption is faster than asymmetric one)
So this is the way I could successfully get a Request Token in the OAuth Playground:
Set 'oauth_consumer_key' to anonymous (unless you have
registered your application and have a real Consumer Key)
Set 'consumer secret' to anonymous (unless you have registered your
application and have a real Consumer Secret)
Choose https://www.google.com/analytics/feeds/ as the scope of request.
Press 'Request token' button
Result:
GET /accounts/OAuthGetRequestToken?scope=https%3A%2F%2Fwww.google.com%2Fanalytics%2Ffeeds%2F HTTP/1.1
Host: www.google.com
Accept: */*
Authorization: OAuth oauth_version="1.0", oauth_nonce="116d4df85e784f51cf40f0bc3a967883", oauth_timestamp="1322083727", oauth_consumer_key="anonymous", oauth_callback="http%3A%2F%2Fwww.googlecodesamples.com%2Foauth_playground%2Findex.php", oauth_signature_method="HMAC-SHA1", oauth_signature="vVxpbtHlTR%2BJ1yT%2BYS1HOvRzhOs%3D"
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Date: Wed, 23 Nov 2011 21:28:47 GMT
Expires: Wed, 23 Nov 2011 21:28:47 GMT
Cache-Control: private, max-age=0
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Content-Length: 118
Server: GSE
oauth_token=4%2F7E_YtZFHuKFPbuAGuCzyj2AsHcha&oauth_token_secret=NHZBJCj2BPxR2HQZhCTwdq2A&oauth_callback_confirmed=true
Now that you have acquired oauth_token and oauth_token_secret, you can press Authorize button. This will redirect you to the login page of Google (if you are not signed in) and then to the page you grant access to the application. By granting access, you will get back to the callback url in the playground with a verifier code. Pressing 'Access token' button, will get you the access token:
GET /accounts/OAuthGetAccessToken HTTP/1.1
Host: www.google.com
Accept: */*
Authorization: OAuth oauth_version="1.0", oauth_nonce="c222a88cc9f027430b239f4cc6f3f154", oauth_timestamp="1322084080", oauth_consumer_key="anonymous", oauth_verifier="TA6vWcDJC51A9YwMNfmUzmUQ", oauth_token="4%2F7E_YtZFHuKFPbuAGuCzyj2AsHcha", oauth_signature_method="HMAC-SHA1", oauth_signature="q9M%2BjeHNxB2ONPd1DPMn6GriUC8%3D"
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Date: Wed, 23 Nov 2011 21:34:40 GMT
Expires: Wed, 23 Nov 2011 21:34:40 GMT
Cache-Control: private, max-age=0
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Content-Length: 103
Server: GSE
oauth_token=1%2Fxy49iwSQEcqSDbo3cKO-UuPLqvt9qKFit9vaLqR6P-M&oauth_token_secret=IJWB1CVSQfYJJPrf9jXv6SS8
*Note: One time, I got the signature_invalid response too, even though I had entered anonymous credentials. But after trying again and pressing 'Request token' button one or two more times I made it. I think this should be due to how nonce and timestamp parameters work to sign the request. This could be the cause of problem. Read this article for more info.
Further reading:
Managing the OAuth key and secret
Registration for Web-Based Applications
Googler here. Haven't fielded OAuth 1 questions in a long time because everyone's moving to OAuth 2 (and you should too) but I'll try to go through the usual suspects on invalid signature errors:
Your server's clock may be wrong. There's a timestamp component and it needs to match ours pretty closely. Try updating your clock against one of the major reference time servers. This happens, but it's an uncommon issue.
Depending on how low-level the OAuth client you're using is, you may have forgotten to supply part of the key used to generate the signature. The key has two pieces, colon-separated, IIRC. In some parts of the protocol, only one half is needed, but for other parts of the protocol, you need both. I've seen cases where someone kept supplying only the first half when both were needed. Actually, I think I made this mistake myself a couple times.
Probably not an issue in your case, because you haven't even gotten past the request token, but OAuth 1 requires you to sign the URI query parameters. Failure to do this will cause the signature base strings to mismatch, thus causing the signature to be invalid.
By far the most common issue is improper encoding. This usually gets expressed as signatures that work sometimes, but fail other times, because sometimes you get lucky and nothing needs to get encoded. I suspect this is what #Meysam ran into based on his comment that he pressed the button a few more times and suddenly it worked.
By the way, if you have to use OAuth 1, you should be using HMAC-SHA1 unless you've got a really good reason to do RSA-SHA1.

Yahoo returns "signature_invalid" when i use OAuth

I am trying to allow users of my website to login using their Yahoo/Gmail accounts.
Gmail went fine. but in Yahoo i have the following php snippet:
$this->options = array('consumer_key' => 'My Key from Yahoo',
'consumer_secret' => 'My Secret ',
'server_uri' => 'https://www.yahoo.com',
'request_token_uri'=> 'https://api.login.yahoo.com/oauth/v2/get_request_token',
'authorize_uri' => 'https://api.login.yahoo.com/oauth/v2/request_auth',
'access_token_uri'=> 'https://api.login.yahoo.com/oauth/v2/get_token',);
$getAuthTokenParams = array(
'xoauth_lang_pref' => 'en-us',
'oauth_callback' => $this->callback_url);//callback to my page
$tokenResultParams = OAuthRequester::requestRequestToken($this->options['consumer_key'], 0, $getAuthTokenParams);
now Yahoo gives
HTTP/1.1 401 Forbidden
Date: Wed, 27 Jul 2011 09:12:19 GMT
P3P: policyref="http://info.yahoo.com/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE LOC GOV"
WWW-Authenticate: OAuth oauth_problem=signature_invalid
Connection: close
Transfer-Encoding: chunked
Content-Type: application/x-www-form-urlencoded
oauth_problem=signature_invalid
in https://developer.apps.yahoo.com/projects i have selected:
delicious social bookmarking (read/write)
Contacts (read)
Social Directory (read/write)
has anybody faced the same problem? have i done anything wrong?
Thanks for your help
As I found yesterday, yahoo's token are huge. Meaning that oauth-php does not store it well so you get bad signature. Here is my solution to the problem: How to use the Yahoo! API with the oauth-php library?

Resources