OAuth2 OIDC, How/When to give JWT to the browser? - oauth-2.0

I'm implementing a SSO solution. Got a general question regarding authorization code flow grant type as described here.
After a user login, the client app would get an ID token. But I cannot find anywhere how/when a JWT should be given to the browser such that it can set the bearer token in the request header for any subsequent request? Is it something not specified in the standard or I misunderstand something?

The browser does not set the Authorization request header automatically. You have to do it yourself using Javascript. This means that a request with such a header must be an AJAX call. If you want to send regular requests through the browser (by navigating to a URL), then you have to use cookies, as they will be automatically added by the browser. (You can keep the value of a token in a cookie and have your backend read a cookie instead of the Authorization header)

Related

OAuth2 Implicit Flow - IFrame Refresh Identity

I'm working on an OAuth2 client for the implicit flow, and am implementing an IFrame-based refresh (since there are no refresh tokens in implicit flow).
What I'm stuck on is trying to figure out the "standard" for passing the access token back to the server. Do I pass back via an access_token query string parameter, or do I have to somehow set the Authorization header when setting the IFrame source (which seems kind of tough)?
Here is what I was told... the authorization server stores a cookie (under its own domain), after the user authenticates for the initial authorization request. The cookie precludes re-authentication on subsequent calls from the hidden IFrame, so there is no need to pass anything from the client as a query string parameter, header, etc.

OpenId Connect Implicit flow, how to maintain session

I am building an Angular SPA app and using Okta as an Idp. since its an SPA so I think I need to use Implicit flow. I have two queries here-
Since in Implicit flow a refresh token is not issued, does it means that th user will be logged out of the app after the token expires and he has to log in again?
Why do I need to use Implicit flow in case of SPA? why not Authorization code flow? since I have control over both the front end (SPA) and back end (REST API) . for example in case of Spring MVC architecture for the web app Authorization code flow is possible.
Thanks,
pchh
Yes, if the token expired, you have to re-autenticate. Normally you still have a valid session on the identity providers site, so you can do a "silent" login using an iframe. Libraries like oidc-client support a silent login, which can do this for you.
You need to use implicit (or hybrid) flow, when you need to access to the access token from your javascript app. With authorization code flow your javascript app doesn't get the access token, so if your API needs an access token for authorization, what are you going to send?
If your auth server supports OpenID Connect (OAuth2 extension) and single sign-on (SSO) feature, to get a new token before the old gets expired, use an iframe with a URL you used for authentication, but add prompt=none parameter (and possibly id_token_hint parameter). See OpenId Connect RFC. The prompt=none parameter tells the /auth endpoint to issue a new token(s) if the user has an open SSO session at your OAuth2 server. If not, the request will fail. There is a separate RFC for session management.
The Authorization code flow requires you to access the /token endpoint, which usually requires authentication (client ID + client secret) and you cannot keep the secret safe in a browser. For this reason, the token endpoint doesn't use to support CORS headers, so you cannot access it using XHR. Using the Auth code flow, you get a code as a redirect URL param (?code=), which gets to the server hosting your SPA (browser sends it there after redirect). The implicit flow returns tokens in hash part of the redirect URL (#access_token=), which stays in a browser (it's not sent to the server), so it's safer.

API Authentication: Place the token in a cookie or a header?

After having developed my first web portal (using railstutorial.org), I'm now making my way in building my first API (with some help).
Authentication for the web portal works with session as well as with a cookie (if the user wants his log in to be remembered).
For the API I understand that using session is insecure; you need to work only with a token. So, just as for the web portal, when a user logs into the API his credentials get checked, and if they are valid a token is generated of which the digest is stored to the database.
But then: I understand there are then three options what to do with the token: to store the token on the user's computer using a cookie, include the token as parameter or use the HTTP header. I read for APIs using the HTTP header is the preferred option.
If using the cookie, it is the same as the 'remember me' option for the web portal: the token is stored in the cookie and a digest of the token is stored in the database. With each API request the cookie is read and it is checked if it's token matches the digest.
Each time the API sends data to the user or the user makes a call to the API, the token is included as a parameter. I understand that this displays the token in the URL, which is not desirable.
My understanding of using the HTTP header fails.
What does it mean to use the HTTP header to send the token, instead of a cookie? What is the process/logic behind it? When to use a cookie, a parameter or the HTTP header?
Am I correct in my understanding that each time the API sends data to the user, it should include the token in the HTTP header? And each call the user makes to the API should include that same token?
I think this link is a good place to start : http://devcenter.kinvey.com/rest/guides/security
Also, reading up on some documentation of HttpAuthentication::Token should give you a basic overview of how/when you should utilize it.
http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token.html
You should look into how a cookie works. Setting a cookie is also sending a standardized http header to the client. When client sends a request, they can send cookie along with the request.
There is also a standard for http token in rails: Link Which is also setting a specific header in the request

How to give user JWT token after OAuth provider redirect?

I'm implementing OAuth (using rauth) and will be giving JWT tokens (using flask-jwt), javascript frontend (Angular1). I have done it for classical cookie/session based app. It works. Now I want to do it with JWT tokens.
If I understand correctly, user is redirected to provider (ex. Google), login into account, my server and provider do the magic, then provider redirect user back to my page. Now I got user profile and that ends the OAuth part. With normal session you give user cookies and the rest of stuff for setting up session, then redirect him to home page.
This is where I'm stuck. Is there any good practice how to give user JWT token after provider send him back? Give it to user as cookie on redirect to home page? Put it in header? As far as I know I need javascript to save token into LocalStorage/SessionStorage.
At the end of the day, the user will be redirected back to our app where a page now needs to be rendered. The only option I see is to return the JWT as a cookie because response headers aren't accessible in Javascript & the only other place would be to embed it in the DOM which would open it up to CSRF attacks.
When the browser is redirected from the OAuth provider it will only have an access code which can be exchanged for an access token on the server side. But best practice says you need to keep that access token secret (not pass it back to the browser).
There is a lot of debate about JWT's in cookies vs local/session storage but in this use-case I don't see any other option than to use cookies. All the use-cases I have seen that describe using browser storage assume an XHR request is being made to obtain the JWT. But this isn't an option in an OAuth flow because the entire browser has just been redirected back to our app.
I don't see another option (for the OAuth use-case) other than keeping the JWT in a cookie to be used for future API calls. But maybe I'm missing something.
Before passing control to Facebook auth, you can initiate a socket connection to your API, then probably show a loading status in your app. Afterwards let Facebook do it's thing. When it succeeds, it posts data to your backend. Your backend does it stuff and passes the JWT to frontend using the socket it created earlier. This seem like too much work & could come with extra bugs if you don't do it correctly.
const jwt = require("jsonwebtoken");
module.exports = {
signToken: function (payload) {
return jwt.sign(payload, "secret");
},
};

Google OAuth 2.0 implementation - registration

In the Google developer console, when you create new app credentials for use in OAuth 2.0, and you specify a web app, it requests that you register callback URI and JavaScript origins.
I don't have a precise understanding of the need to register these.
For the callback URI, presumably this prevents a 3rd party who presents a malicious page to a user from getting the authorization code. However, the client id and secret are still hidden in the app server, so isn't the malicious application unable to do anything anyway?
Furthermore, if the callback URI is already registered, what does registering the JS origins separately accomplish. Unlike the callback URI registration, this is not mentioned by the OAuth 2.0 spec, it's something Google chose to implement.
Thank you for your help!
When you request a token, that token will be passed to the callback URL. By only permitting callback URLs that you have configured in the API console, you are preventing malicious users from spoofing the request and having the token sent to a third party. I suspect the aspect of OAuth that you've missed is that the callback is sent via a browser redirect, so is easy to fake.
Callback URLs are part of the OAuth server flow.
JS Origins come into play when you are using the client (Javascript) OAuth flow. They ensure that any OAuth request has come from a page that originated on your site.
The server flow is ...
OK I think I understand a bit more from reading the spec. https://www.rfc-editor.org/rfc/rfc6749#section-10.6
It is to prevent an attack by a user of the same client An attacker can create an account at the same client and initiate auth flow, but he replaces the redirect URI with his own URI.
He then tricks a victim into following the link to authorize the same legit client they are using. However, the auth code is now sent to the attacker URI.
The attacker then completes the flow by providing the auth code back to the client, which the client uses to complete the flow obtaining the token. However, this token may be associated by the client with the attacker, allowing him to impersonate the victim.

Resources