Laravel Passport: revoke existing access tokens and refresh token before granting a new one - laravel-passport

I have a mobile app that utilizes the Laravel Passport. I want to enforce one authenticated device only. If user A signs in with device A, then user A signs in with device B.
DeviceB is authenticated, and device A is no longer authenticated
If user A signs in with device A again, device A now is authenticated and device B is not.
I am not sure where to implement this and how to do this? Ideally, before generating a new access token/refresh token to a new device, all existing tokens/refresh tokens need to be revoked or deleted.

as i found you want to revoke last token when new login request send to server, so when you generate a new token last token deprecate automatically for example if you use client_credential grant type, you obtain a client_id and client_secret for your user and before any request to server user should pass this client info and get token, so last token revoke automatically this request can be from the same device or different device that not important, just send client info to server and get new access token

Related

Sign in with Apple Security for Linked Account

Assuming you have an existing user management/database on a web platform. Sign in with Apple should be integrated for a quicker login and registration process – although it will always create a regular account linked to an email address (just without a regular password). Is it safe to use the (validated) JWT provided by Apple for authenticating?
Signing in (existing account) would be the following steps:
User taps on "Sign in with Apple" in an app
the generated JWT from Apple is sent to the authentication server
the server validates the JWT using the public keys provided by Apple's API endpoint
the server extracts the email from the (validated) JWT and if a user with that email exists, this user is signed in (API returns internal access/refresh token for the session)
I try to craft an answer for iOS apps. But first clarify the question:
"Is it safe to use the (validated) JWT provided by Apple for authenticating?"
The only known JWT we receive from an Authorization task is the "id_token". Other parameters may be JWTs as well, but these are opaque for the client.
The question is now, if we send the id_token to the app server, is it sufficient to just validate the id_token to hand out the client an access token for the app server's domain? Answer: NO!
When using Apple's Authentication Framework for iOS for Sign in With Apple, the Authorization task returns an ASAuthorization value in the completion handler. This contains basically the following parameters:
user: an identifier
identityToken: JWT the "id_token" (see OIDC)
authorizationCode: A short-lived, one-time valid token that provides proof of authorization to the server component of the app. The authorization code is bound to the specific transaction using the state attribute passed in the authorization request. The server component of the app can validate the code using Apple’s identity service endpoint provided for this purpose. *)
*) If that value does correspond to the OIDC "code" value which will be obtained by a client via the "front channel" aka user agent aka browser, then we should also ensure that an additional mechanism is in place which actually provides a secure "proof of authorization" (Universal Links, PKCE), see Authorization Code Interception Attack.
If these attacks are technically impossible, because the authentication system provides secure communication channels with the app, we don't need PKCE, though.
The id_token contains information about the user that has been authenticated which is stored on the Provider. It's a signed JWT. Even if the JWT can be successfully validated, with the JWT alone the app server cannot be sure that the sender is the one who it believes it is. We don't want to give anyone an access token who is not authenticated!
The app server needs more prove and this will be accomplished with the authorizationCode parameter. This check has to be done on the Provider though.
So, we have to perform two steps:
Verify the Identity Token (id_token)
This will be performed on the app server.
Validate Authorization Code
The second step will be accomplished by your app server obtaining a refresh token form the Providers special endpoints.
With Step 2 we receive a TokenResponse.
If this was successful, we receive an access token and a refresh token. The access token is of no use, but we need the refresh token:
"You may verify the refresh token up to once a day to confirm that the user’s Apple ID on that device is still in good standing with Apple’s servers."
Store this on your app server.
Once after this is all done on your app server you proceed with:
Manage the User Session
After verifying the identity token, your app is responsible for managing the user session. You may tie the session’s lifetime to successful getCredentialState(forUserID:completion:) calls on Apple devices. This is a local, inexpensive, nonnetwork call and is enabled by the Apple ID system that keeps the Apple ID state on a device in sync with Apple servers.
A "User Session" will likely require a domain specific access token and refresh token. You will likely verify again Apple's refresh token when the client requires a new access token on your token endpoint.
So, the last step is your app sending the domain specific access token and refresh token to your client.

Logout from multiple systems in SSO (Single Sign On)

I am implementing SSO for our systems in order to centralize the user authentication and authorization, in which we will have a SSO-server (User and Session Manager) where the user logs in using his/her credentials and then will be able to access all other associated systems.
The implementation of SSO:
First the user will get the session (access token + refresh token)
and they will be stored in the client side.
If he redirects
to the other systems a (single use token) will be generate by SSO
server for that system
And up on the system loading the (single use
token) will be exchanged with a pair of access-token and refresh
token and they will be stored in the client side of that particular
system
And on each server request the session (access token +
refresh token) will be sent through request header so that the
system's server could request this user's authorization from SSO
server.
Access token has less expiry time than refresh token and it's not stored in SSO server and only it's signature is checked for authorization but the refresh token is stored so that we could revoke it later if needed.
(due to the huge amount authorization requests that we will have later on I did not want to stored the access token.)
The problem is that if a user wants to logout, all his/her access tokens should be expired but they are not stored in database and only in client side for each system and I can only revoke the refresh token so the token remains valid until it's expiry time passes and till then it can be used and it means the user is still login.
I use JWT for the token generation and verificaiton.
This is my first question in here I hope I have explained the problem properly.
And I will be waiting for your kind responses.
Preferably use a cookie to store your tokens. When the user has logged out. Simply clear the cookie and return. Now the user does not have the access token and won't be authenticated.
Note: Make sure to make a secure cookie.

Is a refresh token linked to the web applications client ID / client secret?

I have a question regarding security when working with refresh tokens. Lets say I have a web application which has access to a user's google calendar. Therefore I need to do the following steps:
Get a client ID and a client secret from Google.
The user of my web application gives permission to his calendar.
I get a refresh and an access token.
I send the access token to the Calendar API and get access to the user's calendar.
I can refresh the access token with the refresh token, which is saved in the database.
What would happen if someone gets access to my database or in general would have the refresh token of one of my users?
Can an attacker access the calendar with the refresh token or is the token linked to my client ID and client secret? Is it only possible to access the users calendar when my web application authenticates via the OAUTH2 API with my client ID and client secret?
Thank you
Yes, it is/should not be possible to use a refresh token with a different client than it was issued to.
Refresh tokens are typically opaque strings, but in the issuer they should be linked to the authenticated client. That is why you need to send your client is and secret along when you use the refresh token.
Assuming that the client is able to keep a client_id and client_secret from the attacker, the regular approach is to treat and store the refresh_token in the same way. So even though technically it is not possible to obtain a new access token without the client credentials, in practice the attacker would get a hold of the client credentials in the same way as he got hold of the refresh token.

Understanding authentication flow with refresh and access tokens on nodejs app

I know there are already many posts about Oauth, Oauth2, JWT, etc.. I have read many and I more confused than ever so I am looking for some clarification. I will propose my view on the subject and I hope somebody can tell me if my implementation is secure enough or what I am doing wrong and how to improve it.
I am building an API Rest server for serving my resources to my users. Let's suppose it is a bank app where users can deposit, withdraw and transfer money.
I am using nodejs, hapijs, jsonwebtokens, and bcrypt for my server. I want to implement two token authentication flow (Oauth2).
This is the way I am doing it:
User logs in to the auth server by giving some credentials (username and password).
The server verifies the user's credentials, if they are valid, it will grant access to the user and return a refresh token and an access token.
These tokens are saved into the local storage of the browser or mobile device.
The access token:
is signed as a jsonwebtoken.
contains issued date, expiration date (5 min), user data (id, username).
The refresh token:
is signed as a jsonwebtoken and encrypted with bcrypt.
contains a unique identifier
may contain an expiration date
is saved in the database.
As long as the access token is valid, that means, it has not expired and contains valid user data, the resource server serves the user the requested resources.
When the access token is no longer valid, the auth server requests the client to provide a refresh token in order to issue a new access token
The server receives the refresh token from the user, decrypts it, compares it to the one in the database, checks if it has been revoked, and checks its unique identifier.
If the refresh token passes all tests, the server issues a new access token to the client.
If the refresh token fails one test, the server requests the user to re-authenticate.
Notes: I am trying to avoid the usage of cookies.
Questions:
If the user is able to steal an access token, I guess it can also steal the refresh token. So, how can I make the refresh token more secure?
Is my perspective of the Oauth2 flow correct?
What can I improve?
Am I missing something?
The reason OAuth2 is so confusion to many people is because it uses different authentication flows depending on what kind of client is used.
OAuth2 distinguishes two client type, confidential or public. Next to that, there are 2 grant flows that are redirection based (auth code and implicit) which are meant to be used with a browser or browser control.
The other two flows (resource owner password and client credentials) are meant to be used from non-browser apps (CLI, background services, trusted mobile clients).
I've described the different flows and when to use them in more detail in this answer here.

How does Pusher authentication work?

I'm not sure I correctly understood how authentication works in Pusher. Here's a scenario I'm concerned about:
User wants to subscribe to a private channel so the Pusher library calls my server in order to obtain an authentication token.
Server checks if the user is logged in and returns the token
Now the user gets this token and logs out from my app.
User is able to subscribe to the same private channel using the auth token from a different machine, even though they have been logged out.
Is the point 4 valid? Will it be possible to use the auth token after the user has been logged out from my app?
No, option 4 isn't valid. An authentication token is created using a combination of the client's socket ID, channel name and secret. See: http://pusher.com/docs/auth_signatures
The socket ID is a globally unique identifier for the current client connection. If the same auth token were to be used on another machine the socket ID would be different so that auth token would not match the one that Pusher creates when checking the token sent as part of the subscription request from client.

Resources