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.
Related
I'm currently working on a solution where I need to authorize with a OAuth provider that is using Authorization Code with PKCE. I am trying to authorize from my stateless API backend (PHP Laravel shouldn't be relevant though).
The issue I am facing is PCKE sends a code challenge created from a unique hashed code verifier. This works fine until the callback url is hit and I attempt to get the token from the OAuth provider.
When I make a request to get the token I need to send the previous code verifier in order to validate the request and receive the access token.
This lead onto my issue, due to my api backend being stateless I have no way of storing the initial code verifier in session so I can't send it when making a request to the token URL. I have got it working by just hardcoding the code verifier to a known value but this defeats the point.
My question is, is there anyway to use the OAuth Authorization Code Flow with PKCE on a stateless backend?
If you want to keep the described configuration - your PHP backend is an OAuth2 client, I would use the state auth request parameter (RFC) as a key for saving the code_verifier. The state parameter will be returned to you with an auth code.
So you generate random (different) values for state and code_verifier and save them as a key-value pair in a database (or somewhere else). When a response from the OAuth2 server comes, try to find the code_verifier by the state value received from the OAuth2 server.
You can also use your Vue.js frontend as an OAuth2 client, which is stateful, and send an access token to your backend whenever necessary.
Access tokens use to be short lived, so if you need to make more than one request, you will need to take care of generating new ones using a refresh token. Consider that when deciding where to keep the OAuth2 tokens.
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)
I have an ASP.net MVC web application that uses Microsoft's Owin middleware (Microsoft.Owin.Security.OpenIdConnect) to configure OpenID Connect authentication. My identity provider (Okta) is configured to support refresh tokens and I have confirmed that it is working. When signing in, my application receives an Access, ID and Refresh Token as expected. These tokens are validated and returned to the client in a cookie called ".AspNet.Cookies" (the default). On each request, the cookie and these tokens are parsed into a set of claims. Great so far. 👍
The Owin (Katana) middleware does not appear to do anything further with the Refresh Token, so I have implemented a token client to request a new Access Token from my IdP using the Refresh Token. This is working as expected. 👍
Two questions:
When and where should the application check to see if the Access Token is expired and request a new one?
After receiving new a access, id, and refresh token, how and where should the application update the user identity, claims and cookie?
OWIN COOKIE UPDATES
I believe the comment at the end of this post has the type of code you can write - I remember using similar code a few years back.
With OWIN you are using a server side stack secured by cookies so I'm not sure where access tokens are actually used, but maybe one of these is true?
The C# back end uses tokens to call an API
The Web UI downloads tokens from the web back end and makes Ajax calls to an API
PATTERN FOR HANDLING EXPIRED TOKENS
The only reliable pattern to handle expiry is to do this in the API client code:
When you get a 401 response from the API
Try to refresh the token and retry the API call with a new access token
If you can't refresh the token, redirect the user to sign in again
I always implement this with 2 classes, as in this SPA code of mine:
ApiClient - handles API calls
Authenticator - handles OAuth calls
If the Web UI is getting tokens from the web back end and then calling an API, your web back end could provide MVC operations similar to those in my authenticator class:
getAccessToken - get the current access token, though it may fail with a 401
refreshAccessToken - use this if a 401 is received and you need a new token
TOKEN EXPIRY TIMES
It is also possible to check token expiry times in the background - to reduce the number of client 401s. This is not a full solution however, since 401s can occur for other reasons in addition to expiry.
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.
On all OAuth2 documentations i looked, including the Oauth2 spec, the Oauth2 Authorization Code flow ends in the point where the server side holds both the refresh and access tokens.
As a server-side of a web app, what I wish is to not finish the flow here, but response my web user agent with the access\refresh tokens
This in order to have my user agent later make calls to my app's server-side APIs using the access token for auth (the app's server-side will verify the token against the authorization server).
The implicit flow might be the flow i should have been using here (right?), but the authorization server in my company supports only the authorization code flow (and not the implicit flow) for now.
I thought of adding a redirect url as a query param inside of the redirect url of the authorization API.
This way, when the authorization flow will ends, and my app's server side will get the tokens, it will redirect back to the User agent's url, providing the access\refresh tokens as hash fragments
Is it safe for the server-side to redirect to user agent with the tokens this way?
Is there any better practice for redirect back to the user agent?