add query string in Microsoft oauth 2.0 redirect url for token acquisition - azure-active-directory

I'm currently developing an App using Microsoft LIVE 2.0 API
Currently, I’m using these URLs as my authentication endpoints:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize
https://login.microsoftonline.com/common/oauth2/v2.0/token
However, when I sent the request to the token endpoint with the redirect URL as
https://blabla.com/accept_token.php?api_ver=wave5&csrf=AY7F6O4hF0n8yW3i2O_y6N-ky7zzfULiYV_fttLK1S3JgaeQz2GTk9FOeIGBBH5CvkfkEYCyPOCQCujcrij4KDy2wAMZyXqx24jvwZRtzOv0s9ADGYl1iFtvYtkmgeFmZEY&appdata=%7B%22use_case%22%3A1%2C%22type%22%3A1%2C%22flow%22%3A2%2C%22domain_id%22%3A12%2C%22tracked_params%22%3A%22%5B%5D%22%7D
I got errors saying the reply address does not match the reply addresses configured for the application
For the application, I set the reply address to be https://blabla.com/accept_token.php.
Is it possible that I add some parameters to the url and still make it match?

I'm pretty sure the reply url you send must match exactly the reply url registered on the application, including any query strings.
If there is variable state informaiton you need passed throughout the authentication process, you should use the state variable.
https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols-oauth-code
state
A value included in the request that will also be returned in the token response. It can be a string of any content that you wish. A randomly generated unique value is typically used for preventing cross-site request forgery attacks. The state is also used to encode information about the user's state in the app before the authentication request occurred, such as the page or view they were on.

Related

Check authorization token in ReactJS against a Rest API

I am currently trying to design a new web-application for a rest-api service I have running. In basic I am trying to realize the login/logoff system. For authorization-management the API provides three endpoints:
/login, which takes username and password via a POST request and returns a token embedded in a json answer. This token is not a JWT, but its some arbitrary unique string. It is valid for X hours and everytime it used it is reset to be X hours valid again. The validity is check on the server in each request.
/logout, which makes the token invalid on the server.
/validate, which takes a token as json in POST request and checks if it is valid. If not it returns a 401.
Now I realized a login procedure following https://www.digitalocean.com/community/tutorials/how-to-add-login-authentication-to-react-applications . The application finally should used the react-router to provide the different pages. My problem is not how to integrate the validation of the token on each page change and if a 401 is returned, switch to the login page again.
PS: The server is written in C++ and accesses a custom database.
As Suggested By You That You Want To Integrate Validation, So You Need To Create A Component Over The Current Route Component.
It would serve as the private Route and as soon as you get a 401 Response From Your Server You Would Redirect To The Login Page By Updating the Token as empty depenedending upon the storage you are using i.e. session storage or localstorage.
This way whenever your token expires the next request responds with 401 and you are logged out.
Further I am Linking An Example Gist For Creating Private Routes And Logging Out
https://gist.github.com/EduVencovsky/f8f6c275f42f7352571c92a59309e31d

What is the best way to store an admin API token in Next.js ? Feel like storing it client side as http only cookie is risky

I'm working on a e-commerce using next.js and sylius API and the API admin routes are secured using JWT. So in order to fetch products (for example), i need to login to the API, get the token and then fetch the products using the token. The most common method to be able to send the token on every new requests to the API is to store it in a HTTP-only cookie.
As the pages are generated statically, i feel i don't need (and want) to expose the API token to the client. So i'm wondering the best way to store the token ?
Here the different options i have in mind right now:
store the token as a http only cookie and use it server side (with a proxy using next js API pages) in order to call the sylius API. Like i said, i'm not confortable to store the API token into the client, it seems risky to me, as it will be exposed to everyone, and with that token you can access the admin API.
configure the API in order to prevent the token from expiring, and store it in the next js app as an environnement variable (.env.local), so that it's not exposed to the client and can be used for fetching the api when generating static pages. The official ecommerce theme of Next.Js seems to use that method (https://github.com/vercel/commerce/blob/f770ad7a91059a2ecfbb9de1bac111dfe7016124/framework/bigcommerce/api/index.ts#L82)
store the token somewhere in the next js structure but not as an environnement variable (maybe a config file?), so that it can be replaced if necessary (if the token expires etc).
get the token and store it in the react state as is it will be used once only for generating all static pages. On each build the token will be asked again by the API and then used for fetching the API for exporting the static pages with the content. It don't need to be saved more time than the building step.
For me the last option seems better but i feel i'm missing something there, i'm kinda new to next, so i'm not sure exactly if its a good solution.
Thanks :)
I get a great answer from a reddit user ("supermaguireray"), so i post it as an answer here:
"First of all, in any session management mechanism the correct information needs to live on the correct domains, what I mean is that your client can only have access to a identification information, but never to data used in the server, these can be applied to a server-side session, when a ID for the user data stored on the server is sent to the client (preferably encrypted), or in a JWT where a encrypted string is sent to the client (identification), and decrypted on the server (Data).
With that said, the only reason you should send the API token to the client is if you need to fetch data directly from a browser. Storing as a httpOnly cookie is the most secure way.
In case you only need the cookie fetch data to the next backend, to render your SSG or ISR pages, there is no need to send a cookie to the client. Just store the token in your server. I would store it as env variable. Use next.config.js->runtime-configuration.
Or, you can keep a expiration date for the token, and store the credentials, maybe even in a DynamoDB or FaunaDB app."

Storing json web token

I'm learning reactjs, redux and json web token. I'm new on all of them.
In my sample application user sends information from a login page. If the information is true jwt is created and it is set in the state and sent to the client side. It is set to the localStorage. When an other request is sent from client, token in the localStorage is sent to the server via redux action for verifying.
I read some samples and tutorials. Some of them have sent jwt in the HTTP header.
Do I have to sent it to the header ? Are localStorage and state enough ?
Do I have to sent it to the header?
You must send it to the server in a request somehow. Whether that is as a header or as part of the request's payload, it doesn't matter, however it is more convenient and almost certainly considered better practice to send it as part of the Authorization header. Using the Authorization header will allow you to avoid moving the JWT between a request's body and query parameters depending on its type (POST / GET etc.).
Are localStorage and state enough?
No. Storing the JWT locally on the client does not inform the server of the client's authenticated state. You must send the JWT to the server with each request that requires user authorisation.
Do some reading around JWT. There are plenty of links and libraries available to you online. Here is one to get you started.

How can you implement refresh tokens in a web app - angularjs

I am using token based security in my web app. The server side is wrote using c# and i am using openiddict for logging in and issuing tokens, found here. I am currencyly using Implict flow.
By default my tokens have a lifespan of 1 hour, after that you have to logging again. I have locked down my API to accept bearer tokens only and not cookies.
I wanted to implement refresh tokens but after reading many websites, it appears that implementing refresh tokens on a web app, is not a good way to go due to a hacker getting the refresh token. I know that to use refresh tokens, you must use code flow, instead of implict, which i can do.
How do people get round this situation in their web apps? I cant be the only one who wants a token to last longer than an hour in a web app?
The approach recommended by OpenID Connect is to send an authorization request in a hidden frame with the same parameters as the ones you use for the initial implicit flow request plus prompt=none and optionally, an id_token_hint corresponding to the id_token you extracted from the authorization response.
When using prompt=none, the identity provider won't display any consent form and will directly redirect the user agent to the redirect_uri you specify, with the new token appended to the URI fragment, just like for a classic implicit flow request. You can retrieve it by extracting it from the popup.location.hash property.
If the request cannot be processed (invalid request, unauthenticated user, invalid id_token_hint, consent required, etc.), an error is returned and the identity provider either redirects the user agent to the redirect_uri with an error parameter or stops processing the request.
Note that due to the same origin policy, you can't access popup.location.hash if the current location belongs to a different domain (e.g if the identity provider refuses to redirect the user agent to your client app): it will throw an access denied exception. In this case, it's always better to add a timeout to your "refresh" operation.
Sadly, there are very few libraries that can help you with this task. oidc-token-manager is one of them, but it has a few limitations that will prevent it from working OTB with OpenIddict: it doesn't support raw RSA keys (you have to explicitly use a X509 certificate in the OpenIddict options) and it doesn't send the id_token_hint parameter required by OpenIddict when sending a prompt=none request.

Google OAuth2 flow and id_token refresh

I am having troubles in implementing OAuth in the right way.
I use a client/API architecture (Angular for front and Node.js for back) and I would like user to sign in using Google OAuth authentication only.
Here is what I think is the right way for the moment (tell me if I misunderstood something) :
Angular open a Google popup asking user's consent.
Once the user agree, Google Authorization server sends back to angular a verification code.
This verification code is forwarded to an API endpoint.
Then, the API asks Google Authorization server to exchange this code for an access_token, an id_token and a refresh_token.
Google sends those 3 tokens.
The API uses access_token to retrieve user from Google API
The API persists the user
Here is the little dillema, in my opinion, the access_token and refresh_token should be stored into the database and the id_token should be sent back to Angular client.
This way, it would allow the API to ask for resource in Google API and if the token expires it can still ask for a new token thanks to the refresh_token.
Client-side, the id_token is embedded in all requests thus allowing the API to identify the client and verify his authentication with Google certs from https://www.googleapis.com/oauth2/v3/certs.
Supposing this is right way to use tokens, how could I deal with id_token expiration since client does not have any refresh token ?
Thanks !
I do it slightly different (I have the same basic architecture though).
Angular decides the user needs to log in and displays a login popup.
The url in the login popup is not serviced by angular, but is instead directly run off of the backend server: /auth/google . (I use hapijs and bell, personally).
/auth/google is serviced by a bell plugin and initiates the OAUTH dance.
the end of the OAUTH dance results in my node server generating a local token (I just generate random bytes and store them in redis mapped to user ids)
because the initial login popup was created by window.open, the success page (generated on the api side rather than in angular) can use window.opener.postMessage to communicate the token back to the angular runtime.
This way, all my sensitive google credentials (the user's oauth token, refresh token if needed, and my application's api ID and secret) are only on the server, except for during the OAUTH dance relay when they're in a URL string during the client redirects. This is reasonably secure.
Then for all the actual user interactions with the api, I use the token I generated in step four to authenticate. This could be a JWT if you wanted, but I don't do it that way; I just use redis to map from 'longrandostring' -> userId. That lets me (for example) force everyone to re-login if I wipe the redis database that has all the tokens stored, or I can write a lua script to delete all the entries that map to a certain userid.
If you need a refresh token, you can set access_type=offline in the initial request to oauth2/auth, and you'll get a refresh token as part of the response, unless you've previously gotten a refresh token. You can then persist it on the server side and get new access tokens as needed. If you set approval_prompt=force as well, you'll force a new consent screen and be guaranteed a refresh token (but after some small number of refresh tokens granted to a user, older ones expire on the same application so it's best to only request them if really needed).

Resources