Given an auth token, originally received from Spotify Android/iOS SDK, I want to check with Spotify that the token I am holding is valid. Is there a minimal endpoint for doing this?
Ideally something not data-intensive, as I just want to know if the token is valid. This must be done with Web API and not SDK.
There is no API endpoint for checking whether the access token is still valid. Usually you would store it along with the expires_in value that tells you until when it is valid.
An alternative is making a request to any endpoint from the Web API passing the access token. You will get a 401 Unauthorized status code back if the token has expired.
Related
I am try to approve the prividedge identity management (PIM) request through graph api but when i try to approve it the api is return forbidden. See the below screenshots
The pending request should be approved.
First, I want to know what API permission you consented for using this graph API, because to be honest, I didn't find this graph API, I only found this document which contained the API request you used.
According to the error message, I'm afraid you gave the wrong api permission or you used client credential flow to generate the access token to call the API. So it's better to provide the request you used to generate access token.
Finally, I found an answer here which successfully call the API but with Powershell script. According to this sample, we should give PrivilegedAccess.Read.AzureAD,RoleAssignmentSchedule.ReadWrite.Directory,PrivilegedAccess.ReadWrite.AzureAD delegated API permission and use it to generate access token. We need to use auth code flow/ROPC flow so that the token generated should contain scp claim with API permissions as value. Then using that token to call the API.
You may try request below to generate the access token for a test:
POST https://login.microsoftonline.com/{TenantId}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
client_id=azure_ad_app_id_consented_api_permission
&scope=PrivilegedAccess.Read.AzureAD RoleAssignmentSchedule.ReadWrite.Directory PrivilegedAccess.ReadWrite.AzureAD
&username=user_name_better_to_use_account_with_Global_Administrator_role
&password=password
&grant_type=password
I have react app, which can login user via Azure AD. After that, I created from react app request into my .net core mvc app with header Authorize. But when I added [Authorize] attr into my controller, I get error:
Bearer error="invalid_token", error_description="The signature is invalid"
All I need that my backend app only check scope or role from JWT token and allow to get some data. I know that JWT is correct and react app login user without any problems.
Similar issue to this one:
https://forum.ionicframework.com/t/validating-token-signatures-in-asp-net-core/108226
I summarize the comments and post it as an answer:
Usually the 401 error means that the audience of your token does not match your api. When you use the token to call the api, you will receive a 401 unauthorized error. The access token is issued based on the audience, so you must Make sure to set the scope to your api when you request the token. Of course you can also parse the token, check the aud claim, and make sure it is the api you want to call.
When you expose an api protected by Azure, then you need to set the scope to your custom api, usually api://{api app client id}/scope name, and then you need to add the client application to the api application.
Let's say you are developing a client side JavaScript SPA app (Angular), a backend API for this app (ASP.NET Core in my case) and you use an identity provider that implements Open ID Connect protocol (I'm using IdentityServer4).
Apparently the recommended way for securing the app is to use the OIDC implicit flow between the JavaScript app and the identity provider and if successful the JavaScript app gets an id token and an access token.
Now according to this documentation the JavaScript app is supposed to pass the access token in the headers whenever it calls the API. And I'm not sure what purpose does the id token serve in this case (besides customizing the UI in your JavaScript app)?
But this is the confusing part: The documentation also says you should never use the access token for authentication. But that is the token that my API receives in the request headers, how can it authenticate the user then? If my API receives Post(newRecord), and the API needs to internally fix some audit information on newRecord (i.e newRecord.CreatedBy = CurrentUsername), how can it do that without authenticating the caller??
I think I'm missing a piece of the puzzle. Please any help is deeply appreciated.
Short answer/suggestion
Use Access Token to access API endpoints. From API endpoints, you must use token introspection endpoint to validate token validity (active state) as well as obtain subject who authenticated at authorization server. IdentityServer provide support for this. Documentation is available from here.
Explanation
ID token is intended to be used by receiving client. It will allow your client to authenticate the end user and provide user specific customizations. This is the whole purpose of OpenID Connect (OIDC). On the other hand OAuth 2.0 provide an authorization framework. It replaces user credentials with access tokens, thus improving API access security (compared to basic authentication and storing user credentials everywhere). Hence OIDC is built on top of OAuth 2.0, you get both ID Token and Access token with OIDC flow.
But as you have figured out (and mentioned before), ID token is intended for client. There are could be exceptional cases where ID token get passed between client and a server. This is mainly when both are controlled by same party. But the access token is the key to access API endpoints, correctly.
Access tokens can be an opaque string or JWT. When it's a JWT, API can read and understand the token (self-contained). When it's opaque, only way to validate token at API endpoint is to use token introspection endpoint. If API can validate token validity, then it could grant access (authorize) request. Furthermore, if user details (subject) are available (through JWT or as introspection response), then user specific checks can be executed. This further extends to token scope values. But at the end of the day, you are authorizing the API request and not authenticating the user at API endpoint. That's the highlight. Hope things are clear now.!
I'm using developer sandbox to make all my api calls.
It's website build with laravel 5.2
All api calls are made with guzzle/guzzle.
I'm trying automate sending pdf contracts (creating envelopes) using docusign api.
I followed steps from Using the Authorization Code Grant
I had no problem with:
Starting the Authentication Code Grant
Handling the Response
Exchanging the Code for a Token
Getting the User’s Account and Base URI Information
After I get userinfo, there is only one account, so I used that accounts base_uri for all subsequent api calls
{base_uri} + "/restapi/v2/accounts/" + {account_id}
In all my subsequent api calls I'm also adding header
Authorization: Bearer eyJ0eX...MrhIddzBAQ
where I'm using access_token that I've got in step Exchanging the Code for a Token
When doing a create envelope api call, or any other api call, using access_token, base_uri and account_id I get
POST https://demo.docusign.net/restapi/v2/accounts/<account_id>/envelopes resulted in a 401 Unauthorized response
What I tried
Test using the access_token in docusign API explorer:
I went to API EXPLORER - create envelope
I used Authenticate using Sandbox Account to authenticate with the access_token that I've got in previous calls to docusign. Same for the account_id.
When I click on SEND REQUEST, I get 401 Unauthorized response again.
When I use Authenticate using Sandbox Account, but this time I click on Get OAuth2 token (that generates new token), and I click on SEND REQUEST, I get success message.
Then I copied this access_token (from Request) into my website to test the api call, and this time it worked. It also worked for all other api calls that I was making to docusign.
So, using access_token that I get after Exchanging the Code for a Token, I get 401 Unauthorized for api calls
When I use access_token that I generated in API explorer, all api calls to docusign work in my website.
What I also tried
Use refresh_token to get new access_token. Still 401
Xdebug, going step by step to make sure that all params/headers are set before api call. They are, and they are the same as api explorer.
Guzzle option debug => true to get more information about the request, and to compare with what's sent in API EXPLORER, and they are basically the same, except the tokens.
Postman to make request to api, (just to eliminate any chance that I have errors in my code), with same behavior:
401 with token that I get from docusign
success when using API EXPLORER generated token
I'm kinda lost on what to do next and how to solve this, I'm sure it's something simple, but I can't seem to locate the problem.
Update
I used Larry K's answer and found that my problem was with the scope value in /oauth/auth call. I changed it to scope=signature%20extended, and everything works perfectly!
When you click the Get OAuth2 token in the API explorer, you are going through the complete Authorization Code Grant flow, including the new token.
Since this works, but the token your app obtained via the OAuth Authorization Code flow doesn't work, this tells me that your app has an issue.
Check:
Logout from DocuSign. Login from your app. Are you transferred to DocuSign to log in correctly? And then redirected to your app?
Are you requesting the "signature" scope in your request? Check spelling and capitalization of the scope name!
When you're redirected to your app, your app receives the authorization code as a query parameter. Do you get it ok?
When you convert your authorization code to a bearer token are you storing the complete bearer token? It is quite long.
When you send your Envelopes::create request, are you including a space between the word Bearer and the token itself?
Are you making your API call to demo.docusign.net (not .com)
If the above doesn't help, then please update your question (you can edit your question itself) with a trace of your request.
I am developing a Javascript app + REST API.
I want users to authenticate with the app (and underlying REST API) via an OpenID Connect Provider for SSO purposes.
Using the Implicit flow I can get an ID token (JWT) identifying the user to my javascript app. I was hoping that I could then send this JWT in the Authorize header in requests to my REST API to authenticate the user. However, the problem with this approach is that the 'aud' field of the JWT won't be for the REST API server, it would be for the javascript app.
Does this mean Implicit flow is not suitable for my use case, or am I missing something?
Implicit Flow is designed for untrusted clients (such as JavaScript) to obtain identity and also (optionally) access tokens.
With OpenID Connect your authentication request must contain id_token in the response_type parameter, but it can also include token in the parameter too. See 3.2.2.1 in the spec (http://openid.net/specs/openid-connect-core-1_0.html#ImplicitAuthRequest)
e.g.
GET /authorize?
response_type=id_token%20token
&client_id=s6BhdRkqt3
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
&scope=openid%20profile
&state=af0ifjsldkj
&nonce=n-0S6_WzA2Mj HTTP/1.1
Host: server.example.com
id_token means that you will get back the ID token which you have mentioned. The token means that it will also return you an access token, which is what you would use for accessing your REST api.