I've been provided with a REST API which has authentication type bearer (Security Scheme Type: API Key, Header parameter name: Authorization) and which i use to authenticate the user and then fetch other data (i will only create the front end using react).
As a first step the user logs in and i sent his/her username-password to the prementioned REST API and get back an access and a refresh token.
Is anything wrong with storing these 2 tokens in a cookie in order to use them in subsequent requests? How does JWT comes into play regarding these 2 tokens? Is JWT of any use to me in this situation?
There's nothing wrong in storing the tokens in cookies, but if you're planning to have a Single Page Application with React it should be enough to store these tokens in memory. Once the user refreshes the page you can either make them sign in again or perform a silent login in the background to get a new set of tokens. In both cases the session kept on the Authorization Server should kick in and you should get new tokens without the need of user interaction.
Your tokens will be much safer if you don't keep them in cookies.
JWTs are not a requirement for access and refresh tokens. If you don't have to use them I would recommend going with opaque tokens. That said, since you do not have control over the API you might be limited to the format required by the API. If you don't want to be limited by this format you can set up your own gateway which you can use to perform token exchange or introspection and forward requests to the API with proper tokens (something which is called a Phantom Token pattern.
From my understanding of the question, you are using an identity provider which provides you with access token and refresh token for the users. That means it is a authentication as a service REST API at works here.
The REST API requires an authorisation header to be passed along with the username-password to exchange for access token and refresh token for the users. (correct me if I'm wrong) In this case, you might want to keep the authorisation header away from the users (consult the authentication as a service documentation).
You call the REST API with payloads (the user-password) along with headers like this:
Authorization: ACCESS_TOKEN
However the ACCESS_TOKEN is the one provided by the vendor for you to use the REST API. On success call of the REST API, it should return you with a set of access token and refresh token. You can then use this access token and refresh token to safe guard your own API, API that you control to provide service to your users.
The access token and refresh token might just be JWT tokens (again consult the vendor documentation).
Also if you are using an authentication as a service REST API, check the documentation if they provide a client sdk. In that case, it should show you the best practise of handling the access token and refresh token it returned.
I'm implementing Auth0 with my ASP.NET Core 2.1 app with React front end.
After the user authenticates, I do get both an access_token and an id_token. I'm clear that I send the access_token in the header to gain access to my API methods but I'm not sure how to handle the id_token.
Do I place the id_token in the header as well? If so, what key do I use for it? I'm sending the access_token with the key Authorization -- see below.
Not sure how to send the id_token and would appreciate some pointers on this. Thanks.
You would use id_token to construct the User object in SPA application and access_token is used to access the API. So, you don't put the id_token in the header.
There is a JavaScript library for Auth0 that can help with authentication/authorization tasks: Auth0.js.
The library may help with constructing the user object and refreshing the access token.
We have a successful implementation of SSO with Okta as the IdP and an external PHP site as a SP. We are currently utilizing the Okta Sign On Widget which sends our PHP SP a SAML2 Token.
Question is, can we now change from the widget to the API and still get the SAML 2 token on successful login via the API?
So, Since posting this I figured out that - 'yes you can'. I don't know if this is the cleanest/best way but it works and here is how to do it in case anyone else gets stuck looking into this issue...
Already having SAML2 communication working between Okta as IdP and
PHP site as SP.
Create an API access token in Okta.
Use the access token to post a request for a one-time use token from
the API for a specific user you want to login as:
http://developer.okta.com/docs/api/resources/sessions.html
Redirect the user with the retrieved one-time session token to your
App's embed link with the one-time session token:
http://developer.okta.com/docs/examples/session_cookie.html#retrieving-a-session-cookie-by-visiting-an-application-embed-link
This will log the user into Okta to get a proper session we can then
use to send to our PHP end-point to get the SAML2 token we want but
while utilizing the full customization benefits of the API.
I am following this example https://github.com/Azure-Samples/active-directory-dotnet-native-headless to authenticate user against Azure AD using user credentials (uname,pwd) to acquire a bearer access Token. This token will be sent in the Authorization header to the Rest API. The REST API uses the token to authorize the user using ClaimPrincipal.
Now, in my Rest API, I would want to validate if the user belongs to particular Security Group or not. For that purpose I need to use Graph API. But the problem is, every-time I pass the same Bearer Token to my Graph API, which the REST API has received from Client, it throws "Access Token Malformed" error.
In one of the sample (https://github.com/Azure-Samples/active-directory-dotnet-webapi-onbehalfof/blob/master/TodoListService/Controllers/TodoListController.cs) I found we need to regenerate a new Bearer Token to call Graph API, so do I need to re-generate a new Token to call Graph API? Couldn't I use the same Bearer Token which the client has send to my REST API, to call the Graph API?
Tokens are like bank checks. A check written for you can only be cashed by you. If you want to call the graph from your web API, you can use the token you received as a starting point for getting a new token specifically for the graph. See https://azure.microsoft.com/en-us/documentation/samples/active-directory-dotnet-webapi-onbehalfof/ for the pattern used in this case, you just need to substitute the custom API with the graph.
I want to build small application. There will be some users. I don't want to make my own user system. I want to integrate my application with oauth/oauth2.0.
There is no problem in integration of my front-end application and oauth 2.0. There are so many helpful articles, how to do this, even on stackoverflow.com. For example this post is very helpful.
But. What should I do after successful authorization on front-end? Of course, I can just have flag on client, which says "okay, mate, user is authenticated", but how I should interact with my backend now? I can not just make some requests. Back-end - some application, which provides API functions. EVERYONE can access this api.
So, I need some auth system anyway between my FE and BE. How this system should work?
ps I have some problems with English and may be I can not just correctly 'ask google' about it. Can you provide correct question, please :) or at least give some articles about my question.
UPD
I am looking for concept. I don't want to find some solution for my current problem. I don't think it is matters which FE and BE I use (anyway I will
provide information about it below)
FE and BE will use JSON for communication. FE will make requests, BE will send JSON responses. My application will have this structure (probably):
Frontend - probably AngularJS
Backend - probably Laravel (laravel will implement logic, also there is database in structure)
Maybe "service provider" like google.com, vk.com, twitter.com etc remembers state of user? And after successful auth on FE, I can just ask about user state from BE?
We have 3 main security concerns when creating an API.
Authentication: An identify provider like Google is only a partial solution. Because you don't want to prompt the user to login / confirm their identity for each API request, you must implement authentication for subsequent requests yourself. You must store, accessible to backend:
A user's ID. (taken from the identity provider, for example: email)
A user token. (A temporary token that you generate, and can verify from the API code)
Authorization: Your backend must implement rules based on the user ID (that's your own business).
Transport security: HTTPS and expiring cookies are secure and not replayable by others. (HTTPS is encrypting traffic, so defeats man-in-the-middle attacks, and expiring cookies defeats replay attacks later in time)
So your API / backend has a lookup table of emails to random strings. Now, you don't have to expose the user's ID. The token is meaningless and temporary.
Here's how the flow works, in this system:
User-Agent IdentityProvider (Google/Twitter) Front-End Back-End
|-----------------"https://your.app.com"---------->|
|---cookies-->|
your backend knows the user or not.
if backend recognizes cookie,
user is authenticated and can use your API
ELSE:
if the user is unknown:
|<--"unknown"-|
|<----"your/login.js"----------+
"Do you Authorize this app?"
|<------------------+
|--------"yes"----->|
+----------auth token--------->|
|<---------/your/moreinfo.js---|
|-------access_token ---------->|
1. verify access token
2. save new user info, or update existing user
3. generate expiring, random string as your own API token
+----------->|
|<-------------- set cookie: your API token --------------------|
NOW, the user can directly use your API:
|--------------- some API request, with cookie ---------------->|
|<-------------- some reply, depends on your logic, rules ------|
EDIT
Based on discussion - adding that the backend can authenticate a user by verifying the access token with the identity provider:
For example, Google exposes this endpoint to check a token XYZ123:
https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=XYZ123
I read through all the answers very carefully, and more than half the people who responded are missing the question completely. OP is asking for the INITIAL connection between FE & BE, after the OAuth token has been issued by the Service Provider.
How does your backend know that the OAuth token is valid? Well keep in mind that your BE can send a request to the Service Provider & confirm the validity of the OAuth token, which was first received by your FE. This OAuth key can be decrypted by the Service Provider only because only they have the secret key. Once they decrypt the key, they usually will respond with information such as username, email and such.
In summary:
Your FE receives OAuth token from Service Provider after user gives authorization. FE passes OAuth token to BE. BE sends OAuth token to Service Provider to validate the OAuth token. Service Provider responds to BE with username/email information. You can then use the username/email to create an account.
Then after your BE creates the account, your BE should generate its own implementation of an OAuth token. Then you send your FE this OAuth token, and on every request, your FE would send this token in the header to your BE. Since only your BE has the secret key to validate this token, your application will be very safe. You could even refresh your BE's OAuth token on every request, giving your FE a new key each time. In case someone steals the OAuth token from your FE, that token would be quickly invalidated, since your BE would have already created a new OAuth token for your FE.
There's more info on how your BE can validate the OAuth token. How to validate an OAuth 2.0 access token for a resource server?
let's use OAuth concept to begin,FE here is Client , BE here is Resource Server.
Since your client already authorized, Authorization server should grant
Access token to the client.
Client make request to the resource server with the Access token
Resource server validate the Access token, if valid, handle the request.
You may ask, what is the Access token, Access token was issued by authorization server, grant to client, and recognized by resource server.
Access token is a string indicate the authorization information(e.g. user info, permission scope, expires time...).
Access token may encrypted for security, and you should make sure resource server can decrypt it.
for more details, please read OAuth2.0 specification https://www.rfc-editor.org/rfc/rfc6749.
Well you don'y need User-System on your Front End side.
The front end is just a way to interact with your server and ask for token by valid user and password.
Your server supposed to manage users and the permissions.
User login scenario
User asking for token by entering his username and password.
The server-API accept the request because it's anonymous method (everyone can call this method without care if he's logged in or not.
The server check the DB (Or some storage) and compare the user details to the details he has.
In case that the details matches, the server will return token to the user.
From now, the user should set this token with any request so the server will recognize the user.
The token actually hold the user roles, timestamp, etc...
When the user request for data by API, it fetch the user token from the header, and check if the user is allowed to access that method.
That's how it works in generally.
I based on .NET in my answer. But the most of the BE libaries works like that.
As am doing a project for SSO and based on my understanding to your question, I can suggest that you create an end-point in your back-end to generate sessions, once the client -frontend- has successfully been authorized by the account owner, and got the user information from the provider, you post that information to the back-end endpoint, the back-end endpoint generates a session and stores that information, and send back the session ID -frequently named jSessionId- with a cookie back to the client -frontend- so the browser can save it for you and every request after that to the back-end considered an authenticated user.
to logout, simply create another endpoint in the back-end to accepts a session ID so the back-end can remove it.
I hope this be helpful for you.
You need to store the token in the state of your app and then pass it to the backend with each request. Passing to backend can be done in headers, cookies or as params - depends on how backend is implemented.
Follow the code to see a good example of all the pieces in action (not my code)
This example sets the Authorization: Bearer TOKEN header
https://github.com/cornflourblue/angular-registration-login-example