How to re-authenticate on AD without reloading page? - node.js

I'm working on a SPA where adal-angular lib is used to handle auth on client side. On backend app, passport-azure-ad is used with Bearer Strategy, to issue access token and other stuff(no refresh token though).
When user authenticates, accessToken, together with idToken is saved in localStorage, and with token timeout (which is around 1h).
When token expires, I get error (AADSTS50058) back saying single sign-in failed as it is missing cookie, to confirm identity. I'm not sure who needs to issue this cookie, and why it is not issued.
So I have one choice to manually, after reaching that error, call signIn method, programatically. It works to login, but full page reload happens and user loses work.
So my questions are:
Can this be fixed with missing cookie, who needs to issue the cookie, and will it also do full page reload or not?
If I cannot solve this with missing cookie, is there another way to re-login without doing full page reload?
Thanks.

This error may occur if the third-party cookies have been disabled in your browser.
If you are accessing angular application through Chrome browser on incognito mode. it disables third-party cookies at the home page.
If you are using incognito mode. Re-enable third party cookies in your browser to prevent this error from occurring.
For AADSTS50058 error you need to whitelist the
login.microsoftonline.com endpoint in your browser extension in order
to evade receiving this error again
For using access token, I would suggest to use refresh token, access token has a short life span as it becomes invalid or expires you need to re-login.
So make use of refresh token as it has long life span
However, there are two alternatives,
Set the shorter expiry date 60 minutes to Access Token.
Set the long expiry date 100 days to Refresh Token.
“Access token good for an hour, refresh token good for a year or good-till-revoked” So, you better use both Access Token and Refresh Token to fix this issue
To know more in detail please find these links if they are helpful:
Ref1 , Ref2 , Ref3

Related

When should we refresh access token in frontend?

Let's say we have short-lived access token (15 minutes) and long-term refresh token (7 days).
When should we ask backend to refresh access token?
I see two options:
After user logs in we start a countdown to automatically refresh token one minute before access token expires.
We don't implement timer and we try to refresh access token ONLY if we get 401 response from backend.
In first option I see one advantage -
if access token and refresh token will expired AND user stays on the page, not taking any action, he also doesn't send any http request than the timer still works and user is logged out automatically.
In second option -
if access token and refresh token will expired user will be logged out ONLY if he will make some action on page for example: leave a page or make a http request.
If he will stay on page he won't be logged out automatically.
What is a better implementation on frontend than?
I would recommend option 2 as your default behavior, since it will give you a resilient app. Every OAuth client should do this, since 401s can sometimes also be received for infrastructure reasons in some setups, eg token signing certificate renewal.
Option 1 is an optimization, if you want to reduce 401 responses from APIs. However it can lead to incorrectly developed clients and APIs if you are not careful. Personally I never use it.
Note that an expires_in field is returned with the access token but there is no equivalent field for the refresh token, so the client cannot detect when the user session will expire unless you develop a custom solution.
When coding API calls it is recommended to do this, as in this sample code of mine:
When a 401 is received try a token refresh
On success retry the API call - once only
On failure redirect the user to authenticate again
Out of interest there is an online version of the above app that allows you to test OAuth expiry events to see how this behaves - see my Quick Start page

Telling ember-simple-auth that the user is now invalidated/logged-out, inside a custom authenticator

From a custom authenticator; is there a way of telling ember-simple-auth that a user is now invalidated/logged-out?
Some background: I am building an authenticator with token refresh, similar to oauth2-password-grant. While I haven't experimented with the oauth2 authenticator directly, it seems we face the same issue: if the token refresh fails to update, for example due to an expired token, the user remains logged in as far as ember-simple-auth is concerned.
EDIT: (to address comments for further clarification)
Ah, I use JWTs and the server does not maintain sessions; the server has no idea who is logged in nor does it matter. The authentication is done via username/password after which the server issues a JWT token along with a time when it expires. To prolong the expiry time, you may refresh this token (as long as its valid) and get a new token with an updated expiry time. All is well and good except that ember-simple-auth does keep track of whether the user is logged in, as it should. However, if a call to refresh the token fails the user should be considered logged out (the token is invalid/expired and any attempts to make a call to an API that requires authentication will fail).
My question is how do I tell ember-simple-auth that this user has been logged out.

Some of our clients getting PARTNER_AUTHENTICATION_FAILED

Most of our clients are having no issues whatever with our system. We have an integrator key and our users do an initial link up for integration using OAuth on REST. We store the access/refresh tokens. Works fine. At some point down the road some clients seem to randomly hit this.
We are using OAuth with the REST API and always get a new access token using the client's refresh token if their access token is within 30 minutes of expiring.
Q: If a client's access token expires before they make a subsequent call (some of our clients might go 30 days before having another document to sign) to get a new one with the refresh token can that cause this?
Q: Can the refresh token expire such that they would get this?
Q: Short of the client manually revoking access to the integration on their DocuSign account, what else could cause this?
If you get this error then you need to restart the oauth flow again.
A refresh token does expire at some point. When it expires is a policy issue. To achieve the longest possible refresh token lifetime, request scope extended in addition to signature.
Re:
Q: If a client's access token expires before they make a subsequent call (some of our clients might go 30 days before having another document to sign) to get a new one with the refresh token can that cause this?
A: I'm surprised that you're getting this specific error, but I haven't tried this for awhile. I'd think the error would have a different name.
Q: Can the refresh token expire such that they would get this?
A: Same answer as above re the specific error name. In any case, a refresh token can definitely expire. Requesting the extended scope should minimize this, but at some point an account may set a policy that will also expire extended scope refresh tokens. Bottom line: your app needs to be prepared to ask the user to go through the entire OAuth Auth Code Grant flow again.
Q: Short of the client manually revoking access to the integration on their DocuSign account, what else could cause this?
A: Using the wrong base url for the user. Also, at some point there will be organizational controls that can force policies upon the org's accounts. (Organizations own and control accounts.)

Google API invalid request after access token expires

This is the comment that led me to ask this question.
I've got a server side Node.js app, using googleapis package. Users log in with their Google accounts, and I store tokens in their session. The credentials I get are as follows
{ access_token: '<AN ACCESS TOKEN>',
token_type: 'Bearer',
id_token: '<A LONG ID TOKEN>',
expiry_date: <A TIMESTAMP> } // why do some places say there's an expires_in instead of this
There's no refresh_token because the users have already logged in for the first time and clicked accept, and I didn't store the refresh token (looks like I should've).
So, when the expiry_date is reached, if the user tries to make a request for us to save something to their google drive, I get an error message:
{ [Error: invalid_request] code: 400 } // ...no further details
My 2-part question:
I assume I'm getting that error message because the access_token in my OAuth client object is expired (because the call works fine before the token expires). Is this correct? Why is the error message not more detailed?
In the linked answer at the top, the solution is to force the accept prompt again, get the refresh token, and store it permanently, and use it to get a new access token when it expires. Why is this a better option than just checking if the token is expired, and having a user reauthenticate when we want to make a call to the API? Which is the "correct" way to ensure that my logged in users can always make the drive API call to save their documents?
Right, the 400 response is because of the expired access token. I'm not sure why Google doesn't give more detail, but it's common for services to use the 400 status code to indicate some kind of credentials problem. The definition of the status code indicates that it's a client issue.
Both approaches will work and they each have advantages and disadvantages. The client-side re-authentication method you're suggesting has the advantage of making the implementation simpler, since you don't have to store the refresh token and don't have to implement the refresh process. The downside is that forcing the user to re-authenticate every hour is less user-friendly. At the least they will be redirected away from your app, and they may have to explicitly log in or re-authorize as well. You'll just have to look at the trade-offs and pick what works best for your use case.

Google Oauth2 Contacts API returns Invalid token: Stateless token expired after an hour

What's wrong with my setup?
I am using django-allauth for social signup and recently i added contacts to it's scope. Things are working fine. It now asks for permission to manage contacts and I am able to get contact details of users through the API.
But once i make a request to get contacts of a user(I am not saving any refresh token or accss token at that time), after an hour when i make the request again with same token, It shows this error "Invalid token: Stateless token expired".
However I can still login into the website and the token does not change. However when I logout and login again the token changes and i can again get the contacts using that token for one hour.
What's the issue? What am I missing?
See, when you are logging into the website, you are probably using cookies. So basically you might be using the same session and actually the api is not called.
The time when you are logging in incognito mode or in a diffrent browser, that cookie cannot be used, so this time api is called. For this reason, the token is getting changed.
For example, if after few users have signed up with google, you change the scope of the app, what happens is, if the user has enabled cookies and it has not expired, when he visits your site, it simply logs him in. It does not asks for permissions (that you added recently to scope). But when he logs out and logs in again, then it asks for the additional permission and th token also gets changed.
What you should do is, you should go through th codes of django-allauth and clear it out how they are using the token. You must also know that for getting refresh token, you must have offline access enabled in your configuration.

Resources