I'm coding a project composed by an SPA and an API.
On the SPA, I have a button to link Google or Microsoft accounts to the user's account.
The API can whenever it wants call google/microsoft apis.
I've succeeded with google using the Authorization code flow:
From the SPA redirecting the user to https://accounts.google.com/o/oauth2/v2/auth with query parameters response_type=code and access_type=offline
Send the returned code to the API
The API call https://oauth2.googleapis.com/token to get an access_token and a refresh_token
Tokens are saved in the database, and can be used whenever the API wants.
==============
Microsoft has a similar authorization flow (https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow) but I can't use the authorization_code retrieved from an SPA into the API because of CORS policies.
I'm not using PKCE codes because tokens are retrieved from the API that use client_id and client_secret.
=============
Am I missing something ? Is it even possible to get an authorization_code from an SPA and use it to generate access_tokens and refresh_tokens from an external API ?
Thank you so much, sorry for my english !
In the SPA, many authorization servers and identity providers do not support CORS requests, in such case, your option is to use the Azure AD Implicit grant flow rather than the auth code flow, you can get the access token directly via the /authorize endpoint. This flow does not provide refresh tokens, so your app must be prepared to refresh these tokens periodically.
Reference - Microsoft identity platform and Implicit grant flow
Related
I created a multi-tenant app on Azure Portal and sending request to get token with application's client Id. I am using the following URL to get token on Microsoft Azure AD
https://login.microsoftonline.com/common/oauth2/v2.0/authorize
Sending a get request with parameters client_id={clientId}&response_type=token&scope=user.read+openid+profile+offline_access
However it is returning an access_token on given call-back url
http://localhost:8082/my-callback-url#access_token=EwCIA8l6BAAU6k7%2bXVQzkGyMv7VHB/h4cHbJYRAAATb8xtkaxI5xsVkWM6etOevj7ADopBYP1/hj%2bUz%2bf1ZXH4lpykHkES1XBRBDNRDWwdqAA%2brO2tFlMygiuusVx1EJKvqeV0rPPaNDNX9azpWGzS45BN6WmXKcxzX623enNYJOdo%2bYyTtaMipFapvABOsjHve1nVwfq9zqpmcldnIhXBeGefdQsgqmBNjeAyAbWzifLNtdz6Ybxnbt8nMY5adb82Z8tsfddfDdjrqk%2bu%2b85%2bxKXO9Xop3wdRvrVC9FM46RniA6H3NUKjOMTJAsX4IQLjGjXM4eq9o95lmSzF3zgFOXI1rYwkDRVsFsLOgP8tx0occDcuVPQgMalXR6JREDZgAACIJRWLYJGUcWWAKPx26NmroNGG1xEkPB1kLeGk0Hf8324YZs2InsGvQBFUMU4XzGGNdj0s5rLYKK2ictDstHV1daM241F1M5FiaX1qCgdRXneR9uPzUsSIBOzPJtT1dD4k%2bDxp6Nr4hEnDPlymp5X0SR4v5vUA3aRhnsvmEzBVQDKR7cFvT7NSqVHSr/tTv/epdx81qgJcd6S6xF8oaMc7mn76jgU4YBn8jXYnTfGhUvhNZ8RJyyl71AqZrGr7JS2kStselZUgjavLqc9DdQD9cwPSWu1ketKmGgCjt6lVB3nlaw8Wxq%2by2/YhPznTRFD2wj/vzDOdTzCcZ9mJV%2bKMGcXYQqBiGE0MF8%2bWA1EKSXniT5UiegTfJkvnsgtx6G6sdV0rzFM7Xa9d/dHNDfyV5oGedZtJXE1WCUrEIUZZm/HNhhQyh0WSG0gWm3vOY7NAs13vey9lcIQ6Fllu6W/Ty3HE4llFp/9a3lNcujmlxsCASFUOX6R54xPJMt1ipF5lh5uyZCPoUda46UsrCDnNRg0dhuoSVwJMDHzDbs4NXhX4nhTOze/9koz6p5Ao4DtJ20LqmcylZDoLxUhXIU5vvnBYpiHwanBt2E/rG%2bqVEQbRy/v9fhi0chY0XPzldIm/Lz2l0%2b0MpJ/4l53f9YTRLdEMD8X8Umi35ZvpK9arAqgdRkx4/oWG9m8sxOMY2eASetiAJaU8yjtETgHpBGJTXbDVDpNA1s5NGc9QC%2brcSnGDV0BKIDYxBISR8TiJQVUaPqbNU1Mj3kGyQFnfS0jS83VGVfFCZ4cHkhDq/awLh2JrR0Ag%3d%3d&token_type=bearer&expires_in=3600&scope=User.Read%20openid%20profile
How can I validate this access token? or how can I get a JWT token instead?
Your scopes are user.read+openid+profile+offline_access.
That first one is a Microsoft Graph API scope.
It's actually short-hand for https://graph.microsoft.com/user.read.
So you will get an access token that is meant for Microsoft Graph API.
The other scopes you defined affect the id token (openid, profile) or get you a refresh token (offline_access).
This means you cannot and should not validate the token.
Only Microsoft Graph API should be validating this token, since the token is meant for it.
If you want an access token for your API, you need to use a scope defined in the API's app registration (Expose an API section).
I have an secured API student API which I am able to access via OAuth2.0 client credentials flow which creates an access token using IConfidentialClientApplication app and accesses secured app.
Now comes to access the secured API using OAuth 2.0 Resource Owner Password credentials. I have mostly used the code in microsoft github page.
https://github.com/azure-samples/active-directory-dotnetcore-console-up-v2
I am able to sign in using username and password, able to generate access token as well. But this access token is not able to access my secured student API. Though the sample code is able to access the Microsoft graph API, it is not able to access my secured API.
I tried to allow public client flow for my secured student API as well and decrypted both the access tokens to see the difference. There is a lot of difference. What I noticed here is in ROPC flow are using IPublicClientApplication where I am not able to give the ResourceId while acquiring token. So "aud" is different in ROPC token and other fields as well.
Can anyone tell where I may be going wrong or how to fix the above scenario?
I think you may need to perform these 2 steps to get a token valid for your own API:
Expose an API scope in your Azure AD API Configuration
Add an API permission in your Azure AD Password Client Configuration
See step 6 of my Azure AD Blog Post for how this looks. The article also explains some token differences.
I have configured an OAuth 2.0 server for my Azure API Management. I have tested it using Developer Portal (Legacy) to generate Auth Code and it worked fine. However, I want to implement it for a machine to machine scenario and need to test it with Postman to generate a jwt from an endpoint. I'm not sure how I can do this. Need Help.
You will have to implement the Client Credentials flow for the server to server OAUTH Authorization flow. Following blog provides you with the step by step process to set up the Client Credentials flow.
"OAuth 2.0 Authorization with the Client Credentials Flow on Azure API Management"
I follow another practice on top of the steps mentioned in above blog post. I create a token endpoint specifically to get the access token and I implement the logic to call the AAD token endpoint in this API rather than giving the azure AAD url to external customers
Update: Authorization code grant flow can not be tested using the API testing tool as the flow requires explicit human intervention to authorize the app to grant access to the resources.
I already made the authentication flow with the Microsoft Graph/Azure AD authentication. Once I get the authenticated user's token I store them in his cookies. To validate the user's token I call the Microsft Graph API resource /me. This does not seem a good approach because basically everytime time a client does a request to my API, he is basically doing 2 requests because my API requests Azure AD for validation.
Is this a good flow?
No, it isn't.
Your front-end should acquire an access token for your API, which the API can verify using its digital signature.
The token will contain some info about the user as well as the app that acquired it.
The way in which the front-end acquires the token depends on the type of application.
Front-end single page apps use implicit grant flow for example.
Do note that you have to specifically ask for an access token for your API.
As long as your back-end is then configured with standard JWT Bearer authentication,
all is handled.
This is done by specifying the authority as your Azure AD tenant (or the common endpoint if it's multi-tenant),
and the standard bits for JWT authentication should download the public keys from Azure AD's metadata endpoint, which it can then use to verify validity of any access token it receives.
You do not have to validate tokens for an api that's not yours (issued to your AppId Uri).
For example, Graph validates the tokens that are sent to it (issued for "https://graph.microsoft.com).
If you build and register in Azure AD an Api of your own (say AppIdUri="https://myapi.mydomain.com"), your clients will request and receive access tokens with aud claim set to "https://myapi.mydomain.com".
The clients themselves don't need to validate the access token issued for your Api But your Api, when it receives those access tokens, has to validate them. The validations, among other things will validate the access token was issued to "https://myapi.mydomain.com".
Try out this sample, to get a good understanding around concepts of token validation.
How to get authorize and then get access token in Box API using Console or Library project in C#. I have tried authorize API but it returns HTML. I need only THE_AUTHORIZATION_CODE so that it can be passed into Token API for getting access_token.
Or can there be an enterprise access_token which is gotten through the web portal, just like developer token, but which never expires?
Today I discovered that Box is making available a new service called 'Box for Developers' that enables server-to-server token grants and does not require end-user authentication. It's currently in beta. Read more about it.
The BoxDevEditionHelper package provides an implementation of the server-to-server OAuth workflow.
Original Post
How to get authorize and then get access token in Box API using Console or Library project in C#.
OAuth2 requires the user to authenticate with the service in a browser or embedded browser window. There are no exceptions to this requirement.
Or can there be an enterprise access_token which is gotten through the web portal, just like developer token, but which never expires?
No. All Box access tokens expire after ~60 minutes. Access tokens granted through the standard OAuth workflow can be indefinitely refreshed, but the tokens granted through the developer portal do not follow this workflow and thus cannot be refreshed.
I have resolved it By using call oauth2/token API, which returns access_token and refresh_token. access_token will expire as mentioned by #Jonh in above post. But you can store refresh_token in persistence storage. When access_token expires you can get new access_token by using refresh_token by calling same token API.