At the moment I'm still studing a solution for implementing the ADB2C logout for my desktop application (we implemented the Access tokens (used for implicit flows)). So far what I discovered is making me very confused about the purpose of the Logout feature in AD B2C (and probably in OpenId as well?). I realize the following things:
Log out process doesn't revoke the id tokens already issued
nothing stops a blocked user from using their refresh token (granted before the block) to get another access code, and continue to do so until they sign out themselves (from here)
From this link (actually the same..) they suggest to use the Azure Graph command "invalidateAllRefreshTokens", but from the Official Microsoft documentation seems is still in beta and is not supported in production.
So at the moment I'm wondering what is the real purpose of using the signout process. Seems I should take care of it all by my self (and that's fine), but should I still need to call the signout endpoint? Here they say:
If your app didn't go to the logout endpoint, the user will reauthenticate to your app without entering their credentials again. The reason is that they'll have a valid single sign-in session with the Microsoft identity platform. But at the moment I can't understand this sentence (probably bacause I'm still a little bit shocked from all these bad news). So my question is: how do you complete your logout process? Is there any considerations I shoud pay attention while I'm logging out from my desktop app? Thanks for your patience and time.
When you call the logout endpoint, a few things happen:
Access and Refresh tokens are destroyed by the client or confidential server
AAD B2C Session cookies are cleared
The point of the logout here is such that when the legitimate user requests to logout on a specific device, to login again, the user MUST provide credentials. Imagine a shared device in a family home, or in a library. Users must logout to protect THEMSELVES.
Everything you have stated concern over is in reference to a legitimate user who captures their tokens and replays them. That is not a concern when the user IS the one who authenticated in the first place, and IS the one who could reauthenticate anyway to obtain those tokens.
If your concern is around YOU as an ADMIN forcing the end user to lose complete access because YOU demand it, that is not achieved by the USER voluntarily logging out, it is determined by YOU as an ADMIN calling the /revoke endpoint on demand (albeit the AAD B2Cs session cookie will not be invalidated, only the refresh token/s).
In this case, the user will remain logged in until their Access Token expires. And if the account is marked as disabled at time of token revocation, they will not be able to authenticate again regardless. If this scenario is paramount to your service to operate securely, you want to reduce the Access Token lifetime (minimum: 5min).
Related
We have built a React web application that authenticates users with Microsoft via OAuth ( #azure/msal-browser package). Users are redirected to Microsoft auth page during signin, and then redirected back to our site once authentication has completed successfully. This is all working as expected.
However, we are in a position where we wish to add a custom PIN mechanism to protect some of our workflows. PINs will be encrypted/salted and stored in our own API, along with the existing mapping between Microsoft/Azure users and our own user state/records. In order for users to change/reset their PIN, we want to force them to reauthenticate with Microsoft before changing their PIN. I have not dealt with OAuth2 in a while, and am not entirely certain how this might be possible (since current auth workflow does not involve our server at all).
Ideally, users would navigate to the "Reset PIN" page and initiate the workflow. If possible, authentication would be handled through a pop-up (so as to not lose page state), which I think is possible as per documentation? If this is not possible, even a redirect to the same page with a specific query parameter (to indicate post-authentication) could work. The user would then be able to change/confirm their new PIN. At this point, a request would be sent to our API, including both the PIN and something from Microsoft that would allow our server to validate that the user did indeed just re-authenticate (proving they can change the PIN).
The primary sticking point is that our API must be able to verify that the user has just re-authenticated with Microsoft! One way to think about it would be that if a user gained temporary access to an unlocked authenticated workstation, they should not be able to perform restricted actions (as they do not know the PIN), nor be able to change the PIN (as they do not know the user's credentials). Yes, yes, I know physical access is effectively a compromise to any security, but this is a higher-level requirement...
I am guessing this workflow is possible, but am not certain how it might be possible. Would we use a different authentication workflow for this particular use case? Any pointers on a workflow we could investigate or use for this?
I can give you some info about how this should work. This type of flow can require a high level of extensibility in the authorization server though.
CLIENT REDIRECT
The client can send the OpenID Connect acr_values parameter, indicating the assurance levels it requires. In your case you would send two values.
CUSTOM AUTHENTICATION FACTOR
The user will perform standard authentication first, eg passwords. Then you would implement a custom second factor that uses the user identity and some custom logic to call your custom API.
ACCESS TOKENS
After authentication has completed, the authorization server will issue access tokens to the client. High privilege claims should only be included when strong authentication has been used. Some kind of scripting would be used here, that can read authentication result attributes.
API AUTHORIZATION
APIs should receive short lived access tokens. If it contains the high privilege claim, you know that your PIN requirements have been met.
CAN YOU SIMPLIFY?
It feels suspect to do your own PIN management. Can you outsource this, eg use a second factor of time based one time password (TOTP) instead? Mobile platforms such as the Google authenticator app provide tested solutions.
With IdentityServer4 I need to allow a single user session per time. If the user authenticates with device A and then with B, session and access token must be invalidated for A and, even better, client A could receive a notification that user has logged out in a second step.The main thing is making the server force invalidate session and token. There are similar questions, one of them redirects us to the following link:
https://github.com/IdentityServer/IdentityServer4/issues/736
where it is explained to use backchannel logout and in the login method of the identity server to obtain the previous IdentityServer sessionID that should have been persisted somewhere. Then I should send logout tokens to all clients.
Another solution is given here
How to Logout user from a particular session Identity Server 4, .Net Core?
telling us to use an ITicketStore implementation to be able to invalidate the session.
The configuration used is IdentityServer4 with authorizaton code flow with PKCE. Which approach is best for my case? Is there another approach where I could simply delete the access token in the id server database?
I think in your case probably a combination of both. In our real-world implementation we combine server-side storage of sessions via ITicketStore (stored in a custom database with sessions linked to user accounts and also storing the list of client IDs for each session) with the ability to trigger back-channel logout of any session at any time (i.e. not just via the default user-triggered mechanism).
In our case we do this to be able to invalidate sessions for other reasons (e.g. password or other security setting changes, a "log me out of everything" feature, impersonation rights being revoked etc) but this approach could form the foundation of a "single session per user" feature should you wish.
I am working on a integration with Salesforce using REST APIs and, as part of the project, I need to send updates to Salesforce and these updates are not user triggered, they are system triggered.
Because of that, what I expect to see on Salesforce Field History is not a user name but the name of our Connected App (the app that made the update).
What I see today is the user name because the way the integration was made initially using OAuth Authorization Code flow.
To change that part of the project, I followed the link (OAuth 2.0 JWT Bearer Flow for Server-to-Server Integration): https://help.salesforce.com/articleView?id=sf.remoteaccess_oauth_flows.htm&type=5
Making that, I was expeting to generate a token for a System, not for a User, but that's not what happened: when I used the token generate from the JWT Bearer Flow and ran the update, the Field History still shows the user name.
What could I do then?
Which are the options in Salesforce to achieve the behavior I'm expecting?
The most important, in my opinion, is to have a Token for our system, not for a user.
Thanks!
Everybody is an user in Salesforce. Even if you access unauthenticated pages (some contact us form? case or lead capture) - it gets tracked under special Guest User.
It sounds stupid but gives you unified interface to control permissions (Profiles/Permission sets). You want guests to access only FAQ articles and make cases? Sure thing, do it in profile, don't get paranoid about people trying to guess right URLs. You think an app was hacked? You can terminate the session just like any other "user". Want to allow login only in certain hours and from certain IP? Sure.
An app connecting with JWT will still need username (main difference being it's "just" certificate for signing the request instead of password).
Your best bet is to create dedicated "Mr System", "SystemX integration" account. It sounds like waste of license but in the long run saves you questions "why did you edit my account at 1 am" and you could even use it as backup account if you use SSO and it ever fails...
What I'd like to do is end all sessions for a user when a user changes/resets their password (using ASP.NET Core Identity). I'm using the oidc-client-js library inside of a SPA. I've figured out how to end the current session for a user and cause any tabs that're in that same session (say, other tabs in the same browser windows) to recognize the session is over via the check session iFrame, but any other sessions (say in an incognito window) still seem to have the session functioning, even if their refresh tokens/all persisted grants for that subject ID have been revoked.
Is there some way to make that iFrame return to the client that the session is over for all sessions, like maybe have the iFrame page be checking the persisted grants for that session or something? I'm okay if a currently issued access_token continues working (they're short-lived), but just want the refresh tokens to be invalidated and the session to end.
Option 1
There is an OpenID Connect Session draft specification which would do what you want - it allows front end clients to check the current session state via an iframe. This is a draft and may not be implemented by ASP.NET Core Identity though.
https://openid.net/specs/openid-connect-session-1_0.html
Option 2
An alternative mechanism for resolving your problem programatically is by putting a check in your token exchange code. Your access tokens will presumably be relatively short lived, and so the front end has to regularly acquire new access tokens (either via refresh token, or by id token on the implicit flow for instance.
In your token exchange you could check for timestamp when the password was last updated.
If it is more recent than the timestamp when the token was issued, then instead of issuing the fresh access token you could return a 401 and manage a redirect to your authentication endpoint by a mechanism of your choice.
This doesn't instantly log the user out of alternative browser windows, because it depends upon the expiry window of your access tokens. If does have the advantage of working cross browser though, because it doesn't depend upon browser specific session information. It can also check for customers who are blacklisted, or who have changed their email address and other checks which might be relevant to a desire to force re-authentication.
For belt and braces you can use both these techniques.
I'm implementing a Service Provider proof-of-concept for SAML/SSO authentication using Kentor.AuthServices. The use case is a kiosk style application on which numerous different users may be authenticating one after another as they sign up for our service.
The problem I'm having is as follows: after logging out the user is unauthenticated as expected (User.Identity.IsAuthenticated == false). But when the next user goes to log in, the previously logged out user is re-authenticated without having to enter credentials. Is that expected behavior? If so, is there a way to prevent the behavior (other than manually dumping cookies)?
What is most likely happening is that you are indeed terminating the local session on the SP. But when you try to log in again, the Idp still has an active session and automatically reauthenticates with that one.
To work around that you need to use Single Logout. AuthServices has support for that as of 0.17.0. To enable it, you need to have a service certificate configured (logout messages need to be signed). And of course your Idp must support it. Check for Logout endpoints in the Idp metadata.