How to Validate an Access Token for OAuth2 + PCKE flow - api

According to this document
https://developers.onelogin.com/openid-connect/guides/auth-flow-pkce
Token Endpoint for PCKE flow is None (not Basic or POST)
So, how can I use the validation token API https://developers.onelogin.com/openid-connect/api/validate-session because it supports Basic authentication or POST but not for None (PCKE) I can't find any information relate to this.
NOTE: I have tried to request with Basic authentication and without + client_id, client_secret as a parameter but not working.
response 401 Unauthorized
{
"error": "invalid_client",
"error_description": "client authentication failed"
}

I'm using OIDC with PKCE, and I managed to call the https://openid-connect.onelogin.com/oidc/token/introspection endpoint with a token retrieved via the authorization code flow:
$ curl -i -d "token=...&token_type_hint=access_token&client_id=..." https://openid-connect.onelogin.com/oidc/token/introspection
HTTP/1.1 200 OK
Cache-Control: no-cache, no-store
Content-Length: 304
Content-Type: application/json; charset=utf-8
Date: Thu, 25 Apr 2019 23:37:42 GMT
Pragma: no-cache
X-Powered-By: Express
Set-Cookie: ol_oidc_canary_040819=false; path=/; domain=.onelogin.com
{"active":true,"sub":"...","client_id":"...","exp":1558819177,"iat":1556227177,"sid":"...","iss":"https://openid-connect.onelogin.com/oidc","jti":"...","scope":"openid profile email"}
Both the access_token and refresh_token returned from the auth code flow https://developers.onelogin.com/openid-connect/api/authorization-code-grant worked, and the access_token only returned {"active":false} after it expired.
Make sure you are not setting the Authorization header, and only set your client_id in the payload.

Use client_id and code_verify in the POST body. That will authenticate the request on that endpoint.

Related

Getting a new refresh token when using one to get an access token dropbox v2 api

In Refresh token is not returned from Dropbox API when using grant_type=refresh_token
The poster asks why he's not getting a new refresh token when using the new dropbox v2 api.
The answer is that it's not needed. Refresh tokens don't expire from dropbox unless revoked.
Is that still the case? I'm reading in https://developers.dropbox.com/oauth-guide
That "When using refresh tokens, your call to the /oauth2/token endpoint with the grant_type of authorization_code will return a new short-lived access token and a new refresh token, which should be securely stored."
But I'm still not seeing a refresh token when I use one to get an access token.
Request:
POST https://api.dropbox.com/oauth2/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: api.dropbox.com
Content-Length: 363
Expect: 100-continue
Connection: Keep-Alive
refresh_token=<TOKEN>&grant_type=refresh_token&client_id=<ID>&client_secret=<Secret>&scope=account_info.write+account_info.read+files.metadata.write+files.metadata.read+files.content.write+files.content.read+sharing.write+sharing.read+file_requests.write+file_requests.read+contacts.write
Response
HTTP/1.1 200 OK
Cache-Control: no-cache
Content-Type: text/javascript
Date: Thu, 29 Apr 2021 13:30:50 GMT
Pragma: no-cache
Server: envoy
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Server-Response-Time: 35
Vary: Accept-Encoding
X-Dropbox-Response-Origin: far_remote
X-Dropbox-Request-Id: 744233e362ac4b20a00e7a862ae90a16
Content-Length: 395
{"token_type": "bearer", "access_token": "token", "expires_in": 14400, "scope": "account_info.read contacts.write file_requests.read file_requests.write files.content.read files.content.write files.metadata.read files.metadata.write sharing.read sharing.write"}
I'm using the .net api to exchange my refresh token for an access token. But don't see how I'd get the new refresh token back even if it was on the wire. Which it does not appear to be. The refresh tokens themselves don't seem to be expiring when I use them to get access tokens. Will that change in the future?
_DropBoxClient = new DropboxClient(string.Empty, dbap.RefreshToken, sApiKey, sApiSecret, config);
var newScopes = new string[]
{
"account_info.write",
"account_info.read",
"files.metadata.write",
"files.metadata.read",
"files.content.write",
"files.content.read",
"sharing.write",
"sharing.read",
"file_requests.write",
"file_requests.read",
"contacts.write"
};
bool success = Task.Run<bool>(async () => await _DropBoxClient.RefreshAccessToken(newScopes)).Result;
The Dropbox API /oauth2/token endpoint does not return a new refresh token during the refresh process, nor are there plans to make it do so. The official documentation for the Dropbox /oauth2/token endpoint can be found here.
The Dropbox OAuth Guide is referring to when you call /oauth2/token for grant_type=authorization_code, i.e., when first exchanging the authorization code for a short-lived token and (optional) refresh token. (Apologies the "new" there is misleading. We'll fix that up.)
When you call /oauth2/token for grant_type=refresh_token, i.e., when using a refresh token to get a new short-lived access token, it will not return another refresh token.

Cannot generate an authorization code on API Explorer

I'm trying to collect and download my lifelog user data. The first step into doing this is getting a user-access token. I am encountering problems while requesting authorization.
From the sony developer authenticization page I am told to input the following code into my API explorer:
https://platform.lifelog.sonymobile.com/oauth/2/authorize?client_id=YOUR_CLIENT_ID&scope=lifelog.profile.read+lifelog.activities.read+lifelog.locations.read
I am supposed to receive the authorization code as such:
https://YOUR_CALLBACK_URL?code=abcdef
However, this is what the current situation is actually like:
I have replaced my actual client ID below with MY_CLIENT_ID for security reasons
INPUT:
GET /oauth/2/authorize?client_id=MY_CLIENT_ID&scope=lifelog.profile.read%2Blifelog.activities.read%2Blifelog.locations.read HTTP/1.1
Authorization:
Bearer kN2Kj5BThn5ZvBnAAPM-8JU0TlU
Host:
platform.lifelog.sonymobile.com
X-Target-URI:
https://platform.lifelog.sonymobile.com
Connection:
Keep-Alive
RESPONSE:
HTTP/1.1 302 Found
Content-Length:
196
Location:
https://auth.lifelog.sonymobile.com/oauth/2/authorize?scope=lifelog.profile.read+lifelog.activities.read+lifelog.locations.read&client_id=MY_CLIENT_ID
Access-Control-Max-Age:
3628800
X-Amz-Cf-Id:
HILH9w3eOm-6ebs_74ghegYQyWS4xyqA1l0gXPRJuuubsoZ6eiiS3g==
Access-Control-Allow-Methods:
GET, PUT, POST, DELETE
X-Request-Id:
76caccfc976d40259ef30415d10980e9
Connection:
keep-alive
Server:
Apigee Router
X-Cache:
Miss from cloudfront
X-Powered-By:
Express
Access-Control-Allow-Headers:
origin, x-requested-with, accept
Date:
Sun, 22 Jan 2017 03:00:42 GMT
Access-Control-Allow-Origin:
*
Vary:
Accept
Via:
1.1 dc698cd00b7ec82887573cfaba9ecca6.cloudfront.net (CloudFront)
Content-Type:
text/plain; charset=utf-8
Found. Redirecting to https://auth.lifelog.sonymobile.com/oauth/2/authorize?scope=lifelog.profile.read+lifelog.activities.read+lifelog.locations.read&client_id=MY_CLIENT_ID
Nowhere can I see the authorization code in the above code. I even tried copying and pasting the URL (on the last line) into my browser, it says "localhost.com took too long to respond"
This is where I input my request
I am not sure whether it is an issue with the callback URL. I don't have an actual website or app made, I just used the default localhost
I am a beginner in this and would really appreciate all help.

Web API Basic Authentication returns 401

I've build a web api service with basic authentication and using a global DelegatingHandler implementation which I hook up to the web API GlobalConfiguration, in order to extract the username:password credentials from the request and hook an IPrincipal to the HttpContext if the credentials map to a valid user.
I've tested my api thoroughly on localhost and it's working fine, but not quite when hosted on IIS on a VPS.
I've hooked up remote debugging on the VPS in order to inspect whats going on and it turns out that whenever I include the authorization header to my request, the breakpoints I have set on the message handler are not getting hit, meaning that the request does not reach the handler. If I remove the Authorization header from the request, the breakpoint is getting hit and the handler is able to process it.
Since the message handlers are the first that will process the request in the pipeline (from what I know of, correct me if I'm wrong) I guess there must be an IIS or setup issue that I'm not aware of that messes the authentication process.
Fiddler Request Headers
GET http://myip/api/v1/route/parameter HTTP/1.1
Content-Type: application/json; charset=utf-8
Authorization: Basic ZHJpdmVyOjEwMTAyMDAz
Host: myip
Fiddler Response Headers
HTTP/1.1 401 Unauthorized
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
WWW-Authenticate: Basic realm="myip"
X-Powered-By: ASP.NET
Date: Mon, 22 Aug 2016 15:04:15 GMT
Content-Length: 61
{"Message":"Authorization has been denied for this request."}
What could be possibly be wrong, where should I look at for a solution?
EDIT
Had to disable Basic Authentication from the Authentication menu on the right pane setting for the IIS application.

Reddit API Oauth2 "user required"

I am trying to get the installed app to work with Oauth2 on Reddit's api. I am using Windows runtime api's httpclient to make requests, and webauthenticationbroker to get the code to do the GET request to receive the token. I requested a token by using this:
https://www.reddit.com/api/v1/authorize?client_id=" + client_id + "&response_type=code&state=" + "testing" + "&redirect_uri=http://abcd.com&duration=" + "permanent" + "&scope=" + "vote,identity"
And got a code back, so I used POST on this (with the content type being: application/x-www-form-urlencoded):
https://www.reddit.com/api/v1/access_token
with the body being this:
grant_type=https://oauth.reddit.com/grants/installed_client&\
device_id="+id + "&code=" + code
(code and id is the code received in the first step and id is a generated UUID)
Then I got something like this back:
{"access_token": "--5e65dP1dI_1vgLbqvi7zRB6cnU", "token_type": "bearer", "expires_in": 3600, "scope": "*"}
So I extracted the token and got this:
--5e65dP1dI_1vgLbqvi7zRB6cnU
Then I tried to do a GET request on https://oauth.reddit.com/api/v1/me with these headers:
{
User-Agent: (testUWP client by /u/bored_reddit_user)
Authorization: bearer --5e65dP1dI_1vgLbqvi7zRB6cnU
}
I got these headers back with status code 403 reason phrase forbidden:
{
Connection: keep-alive
Server: cloudflare-nginx
Strict-Transport-Security: max-age=15552000; includeSubDomains; preload
Transfer-Encoding: chunked
cache-control: max-age=0, must-revalidate
x-ua-compatible: IE=edge
CF-RAY: 23f5127a6a2911a1-SJC
Date: Tue, 03 Nov 2015 03:42:58 GMT
x-frame-options: SAMEORIGIN
access-control-allow-origin: *
X-Moose: majestic
x-reddit-tracking: https://pixel.redditmedia.com/pixel/of_destiny.png?v=BZoi0ikdGrSYn9U9xM6GWeYcRRb0W50fSQuGYb1Q8Oe7E5WVB6qTA4hRqlx9vDfpLOKzpE3Z5Wo%3D
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
access-control-expose-headers: X-Reddit-Tracking, X-Moose
}{
Content-Type: application/json; charset=UTF-8
}
and this content:
{"explanation": "Please log in to do that.", "reason": "USER_REQUIRED"}
I am at a loss as to what I'm doing wrong, can anyone help me out?
This wiki page on the reddit github gives a pretty good overview of reddit's implementation of OAuth2 and the different grant_types and what circumstances they are appropriate for. This page has some more information. I'm suspecting that reddit doesn't want you storing the client secret in an app that you install on a user's device since you can't keep it secure, and a user could figure out your CLIENT_ID.
I'm glad my comment could point you in the right direction, if you could accept this answer, I'd appreciate the rep.

Office 365 REST Calendar API for creating events failing with HTTP - 403 when authenticated using OAuth bearer token

My azure hosted web API uses the O365 Calendar and Mail REST APIs for creating events and mails on behalf of the users. All necessary permissions have been enabled for the corresponding Azure AD application. My question - Accessing the mail API using the Bearer OAuth token as part of the header succeeds but when I use the same token for the events API, it fails with a 403.
The Documentation I have been following for my implementation is the official msdn one and the update - https://social.msdn.microsoft.com/Forums/exchange/en-US/6fc135ae-f8f9-4b4d-b50b-f00a2bd79a30/office-365-rest-api-mail-calendar-contacts-update?forum=exchangesvrdevelopment
Fiddler trace (Raw view of request) -
POST https://outlook.office365.com/ews/OData/Me/Events HTTP/1.1
Accept: application/json
client-request-id: 00000000-0000-0000-0000-000000000000
Authorization: Bearer <OAuth token>
Content-Type: application/json; charset=utf-8
Host: outlook.office365.com
Content-Length: 287
Expect: 100-continue
{"Attendees":[{"EmailAddress":{"Address":"sample#sample.com","Name":null},"Type":"Required"}],"Body":{"Content":"Hello World","ContentType":"HTML"},"End":"2014-10-22T19:00:00Z","Location":{"DisplayName":"Conf Room M"},"Start":"2014-10-22T18:00:00Z","Subject":"Testing"}
Text view of response -
{"error":{"code":"ErrorAccessDenied","message":"Access is denied. Check credentials and try again."}}
Fiddler trace of the Mail API request that works fine -
POST https://outlook.office365.com/ews/OData/Me/sendmail HTTP/1.1
Accept: application/json
client-request-id: 00000000-0000-0000-0000-000000000000
Authorization: Bearer <OAuth Token>
Content-Type: application/json; charset=utf-8
Host: outlook.office365.com
Content-Length: 171
Expect: 100-continue
Connection: Keep-Alive
{"Message":{"Body":{"Content":"Test","ContentType":"HTML"},"Subject":"test","ToRecipients":[{"EmailAddress":{"Address":"sample#sample.com","Name":null}}]}}
Considering that you are getting a 403 (Forbidden) error for one API, I'd suggest you review the resources enabled for the application. Can you make sure you have Write permissions for the Calendar API? I know you mentioned that you've done this before, I'm just checking in case of the small chance you missed those Write perms.
Sorry for having kept this question hanging.
The issue was with the ClientSecret (either had stale permissions on it or was wrong in the first place). Generating a new one via the management portal fixed this issue.