I'm developing an angularjs web app.
To access server side api, I need to add an id_token header and
I receive an id_token, by using https://accounts.google.com/o/oauth2/auth endpoint.
The crux of the matter is this - the id_token has an expiration date. Before accessing server API, I need to make sure the id_token is not expired yet, but if it is, the obvious choice would be to refresh it.
Is there any way I can refresh the id_token?
I know I could change access_type to offline, and receive a refresh_token, but it does seem pretty weird to ask for an offline access, when basically in my case user interacts with the server only at the moment when he actually using the web app online.
Forget all about refresh tokens and offline access. This method is only applicable for server and desktop apps. To have a refresh token present in the browser would be a massive security hole.
If you read the docs for the Google JS OAuth library, you'll see that it's easy to get a new access token once the current one expires. See gapi.auth.authorize() and note the comment for immediate=true. NB this method is deprecated, although it works. Absolutely everything you need to is at https://developers.google.com/api-client-library/javascript/reference/referencedocs
When the id_token expires, the client requests new tokens from the
server, so that the user does not need to authorise again.
From IMPLEMENTING A SILENT TOKEN RENEW IN ANGULAR FOR THE OPENID CONNECT IMPLICIT FLOW
Related
As there is currently no Auth0 SDK for SvelteKit, I am learning (or at least trying to learn) far more about authentication than I originally intended when setting out to incorporate Auth0 into my SvelteKit app (including server side authentication). The documentation is a little confusing (or maybe it is just massive, or maybe I am just not that bright), so I was hoping to describe my auth flow here for critique (in the hope that this will be helpful to others in the future).
I have reviewed this great post about SPA auth as well as Auth0's educational offerings. Still I am not sure I am connecting the dots properly. Here is my flow. All of this occurs over SSL only.
I create an Auth0 client on the client side using their client SDK (#auth0/auth0-spa-js). That client performs authentication via the Auth0 popup.
Once authenticated, everything works as expected on the client side. But if I want to control access to routes on the server side, I need to get information back to the server. So...
After authenticating, Auth0 creates an ID token (a signed JWT) which is stored in the browser's local storage. I save it as a session cookie (with SameSite=strict; HTTPOnly; Secure; options set) so that it gets passed back to the server with requests for route authorization.
So let me pause right here...I understand that (at least according to some including the Auth0 educational video linked above) the ID token is not supposed to be used for authentication and should never be passed around. That is what an access token is for. However, in this scenario where the exchange is all first party (my client, my server), it is my understanding that it is "ok".
However, it does make me nervous that the Auth0 SDK is not setting the cookie itself. This makes me wonder if I am Doing It Wrong™.
On the server I validate the id_token using a public key, and can then save user details, etc. on the backend if I wish, and allow access to appropriate routes (via hooks.server.js in the case of my SvelteKit app).
When the user logs out, or if the token expires, the cookie is removed.
(As a side note, I have yet to figure out how to refresh the ID token when it expires as the Auth0 client SDK does not seem to ever update the ID token in the browser storage even if it is expired.)
Is that a secure and typical way of going about it?
(For a work in progress working example, see my svelteauth0 repo.)
I'm working on an Absinthe GraphQL API for my app. I'm still learning the procedure(so please go easy on me).
I've a Absinthe/GraphQL MyAppWeb.schema.ex file in which I use for my queries and mutations. My question is how do I use this API for authenticating the user on both Mobile and Web app?
How do set a cookie(httpOnly & secure) in my web app and access/refresh tokens in a single Absinthe API to serve my website and mobile app. Basically what I'm trying to learn is how do I authenticate the user based on specific platform.
If my question sounds bit confusing, I would be happy to provide more information related to my question. I would really be grateful if someone could explain the procedure, I've been very stuck on this for a while.
I would avoid using authentication mechanisms provided by absinthe(if there are any). Depending on what front-end you are using, I would go with JSON API authentication. The flow on server goes the following way:
Create a endpoint for login that will receive a user and password and will return a refresh token.
Create a endpoint for exchanging refresh token for access token.
Use a library like guardian to generate your refresh/access tokens.
Create a phoenix plug for authentication that will check your tokens, guardian has some built-in plugs for this.
Now on device you have to implement:
Ability to save refresh and access token on device.
Have a global handler for injecting access token on authorized requests.
Have a global handler for case when access token is expired. (you usually check if your request returns Unauthorized, then you should request a new access token from the server using your refresh token)
This seems like a crude implementation, however I would advise in implementing your system instead of using a black box library that you have no idea how it works under the hood.
We have a web app in which we allow users to log into the app using any Open ID provider(e.g. Okta, Google, Facebook etc.). We want to implement the correct Open ID Connect prescribed methodology/workflow to keep the user logged into the site.
The existing implementation, looks at the expiry of the Access Token then if it's close to expiry uses a Refresh Token to get a new Access Token to keep the user logged in. I feel like this is wrong. When a user logs in to the web app, the Identity Token is used to Authenticate the identity of the user using the Authorization Code workflow. The Access Token and Refresh Token are stored on the server side. Periodically, the Refresh Token is used to get new Access Tokens to keep the user logged into the site. I believe this is a security risk because -
Imagine if a user is logged onto his OP account in a browser. He opens up Sky and is directly logged into MP because he’s already logged into MP. He then in a separate tab, logs out of his OP account. He will continue to be logged into MP for days on the basis of this Refresh Token/Access Token mechanism! Isn’t this a security risk?
If feel like the correct way to go about this is to use Session Management using iframes as prescribed here on OIDC -
https://openid.net/specs/openid-connect-session-1_0.html
For more context, when a user logs into our WebApp we pull data from the OP's UserInfo endpoint to create a profile within our WebApp and set permissions/roles within our app based on data sent over from the OP's UserInfo endpoint. We continue doing this periodically. For this purpose, I feel like using the Access Token(and using the Refresh Token to get new Access Token) to access the UserInfo API is correct because it conforms to the OAuth 2.0 concept of protecting/authorizing API/Resource endpoints using Access Tokens.
I want to know if this is indeed the correct way to manage how a user should be logged in when supporting Open ID Connect.
I think the first question is whether you want to bind the lifetime of an OpenID Connect provider Single Sign On session with the session of your application. You just want to authenticate a user using their OpenID Connect service. If I logout of Google, I expect to be logged out of GMail, but not a third-party application that used Google for authentication. Would you like to implement Single Sign Out as well?
But if I wanted to be logged out when you logout of the OpenID Connect provider, I would implement the OpenID Connect Session management. There is one thing good to be aware of when using iframes and cookies - browsers have an option to "Block third-party cookies" (that's how Chrome calls it), it's turned off by default, but as far as I know, it disables the SSO functionality when turned on.
I'm not sure why you request the userinfo endpoint periodically. If you just want to check whether the access token is still valid, you could also use the token introspection endpoint.
For security concerns, I would suggest you to read the OAuth 2.0 for Browser-Based Apps RFC. It recommends using the auth code flow with PKCE instead of the implicit flow. With the implicit flow, access tokens transported in redirect URLs stay in network and browser caches and can be used right away by an attacker. The auth code with PKCE needs a code_verifier (one-time secret) in order to be exchanged for tokens. So I would first check how the providers work with a configuration you choose and if it's even supported.
There are SNS application with 2 servers. Web backend server and REST API server.
The web server allows user login/logout with username/password, and show user information
The REST API server provides APIs like /topics, /comments, it should be stateless without session
The REST API will serve other web applications
There are some potential solutions, but neither is security.
Base Auth, the browser hold the username/password
Token with expiry timestamp, the problem is user could stay on the page until token expires
So, is there a way to protect the REST API when calling it from AJAX?
If I have understood your problem correctly I may suggest you use the Token solution. In order to maintain security you may generate new token on every request (& send it to client in response), which should be used to make next request, and disable token if it is once used or has expired.
Sorry, I meant to mention it as a comment, but I don't have enough reputation.
I can see OAuth working well for a fully Ajaxified application, as the local JS code can always replay the Bearer token to the server. However, what happens if we have a page refresh? In that case I assume we lose the token and then go back through the OAuth redirect process to get yet a new access token issued. Is this correct, and are there patterns to avoid this, such as storing the access token in HTML5 local storage?
If you're talking OAuth 2.0 then you can probably request both a refresh token and access (or Bearer) token when you authenticate with the OAuth 2.0 provider. The refresh token should be returned directly to the server hosting the web application, stored somehow (perhaps session state) and NOT ever exposed to the browser. The browser can use the access token to make requests to secured services/endpoints which require it but it should have a short lifetime (regardless of whether or not there was a page refresh). When it expires (again may or may not be due to a page refresh) the client application can make a request to the hosting server where the refresh token was delivered. The server can then use the refresh token to get a new access token WITHOUT the user needing to login again.
There's a diagram of this in the refresh token section of the OAuth 2.0 spec.
There are several variations of how OAuth 2.0 can be used and details may vary with your particular scenario and implementation but hopefully that gives you a high-level idea of how you can avoid prompting the user to re-authenticate when the access token expires or on page reload.