How to disable automatic browser cookie login with Web.TPEngine.Providers.SelfAssertedAttributeProvider - azure-ad-b2c

I am using B2C custom policies.
I am using Web.TPEngine.Providers.SelfAssertedAttributeProvider documented here:
https://learn.microsoft.com/en-us/azure/active-directory-b2c/self-asserted-technical-profile
The signin relying party of the custom policy is working well, except users won't get user/password challenge after a successful login. I guess the technical profile uses browser cookies like "x-ms-cpim-cache|o4wex_p_gejeeak6w_0" for domain b2clogin.com to remember a successful login for at least a browser session.
The Metadata "setting.enableRememberMe" is the default that is set to false.
I need to make sure users are challenged with user/pwd every tinme the signin relying party is called. Is there any way to disable the auto-login with the cookie cache?

Set the session management technical profile to SM-Noop on the sign in technical profile.
For JavaScript apps, this will break silent token calls for an access token.
Other option, for initial logins, send the query param prompt=login which will kill the cookies when the user arrives at B2C. This at least keeps silent token calls working for JS apps.

Related

IdP as the master session

Background
I'm trying implement a browser-based login for a native mobile app from an existing Single Page Application. It uses WebView to render the SPA and it uses Keycloak OIDC as its Identity Provider.
The SPA and IdP is located in completely different domain and authentication is done by redirecting to the SPA domain after a successful login and retrieving the active session (cookie) from IdP domain in one of the SPA's server. The authentication check is achieved by using keycloak middleware which I believe is the protect.js
Summary:
Perform Login -> auth.idp.com
Redirect -> best.app.com
Is Login? -> best.app.com/login
Does auth.idp.com session exists?
User is logged in, redirect -> best.app.com
Token is passed in the URL and is stored only in memory
Token is used to establish WebSocket connection
Issue
Based from the spec, the authorization should happen in the browser / in-app browser, and authorization code must be passed via custom URL scheme. Having that in mind, the SPA that resides in the WebView of native mobile app will never establish a session from IdP's domain since this will be delegated from the browser which is on a different process and obviously using a different cookie store than on WebView in the mobile app, which makes our existing solution to break because it is relying on the IdP's domain cookie.
Proposed Solution
The issue I described above can be mitigated by cutting the reliance on IdP's session and by managing the SPA's own session, which basically means storing the token persistently that can be obtained from the IdP (which the current solution doesn't do).
(I don't want to detail much of the solution since I just want to focus first on the concept of storing the token. I think it's better for me to put this in a separate discussion if someone is interested)
Opinion
It seems like the current implementation doesn't really follow the best practice for OIDC flow but somehow, Keycloak has made some middleware to remove the need to use these tokens (authorization code, id token, and access token)
Relying on IdP's session when implementing SPA or non-web apps seems like not an option, because there is no way to obtain the cookie without reloading the page and provided that IdP session exists in the same cookie store as the SPA.
Redirecting to the IdP's session is not a good user experience for SPA. See the same sentiment here but it seems it does not have any answer: https://lists.jboss.org/pipermail/keycloak-user/2016-October/007937.html
Question
With regards to my proposed solution, i.e., storing the token retrieved from IdP, is there any security flaw or something non-industry standard it's going to introduce? If so, what are those?
Is it typical for OIDC flow to rely on IdP's session (cookie) to check if user is logged in or not?
If answer from #2 is NO, is that authentication flow specific for Keycloak only or does it exists for other IdP as well?
If answer from #2 is YES, is it common for IAM solution to programmatically check if the IdP domain contains a valid session (cookie)?
Is the current implementation flawed knowing we are aiming for SPA?
How does Keycloak handle sessions?
If you're using the default Keycloak middleware in your server and use keycloak.protect() for protecting endpoints, it checks on the request.session['keycloak-token'] which contains the access_token that was created during the token request after user login. If this exist and valid, it means user will not be redirected to Keycloak login page.
How does Keycloak create sessions?
Providing username and password which can be done manually using Keycloak's login page.
Cookies - if you pass valid cookies that are recognized by Keycloak, i.e., KEYCLOAK_SESSION, KEYCLOAK_SESSION_LEGACY, ..., a session will automatically be created.
How to access protected resources?
When using the keycloak-connect client adapters, you can access protected resources if the user agent (browser/app), has a valid session in your server OR if the request contains valid Authorization header.
Standard Solution
Access protected resource via Authorization header and use access_token which the keycloak.protect() also accepts. You can obtain this token in a standard way using Chrome Custom Tabs for Android and ASWebAuthenticationSession for iOS. You can also use AppAuth (iOS, Android) to lessen your work.
Store the refresh_token and access_token from native mobile and inject this in the HTTP request of WebView if possible.
Have a way to check for access_token validity and use refresh_token to request for a new one. If requesting for a new one fails, i.e., the authorization server verifies it's not valid anymore, that means users would need to re login again.
By using the standard solution I have proposed above, you should not need to create a band-aid solution for your issue. Hope this helps anyone that have faced similar issue.

Xamarin Forms Open URI with access token

I have POC Xamarin Forms PCL app and authenticated successfully with MSAL. My REST calls(to read user profile and sharepoint list data) to graph API are all successful.
I am trying to open a sharepoint page in the browser using the token, i.e. without asking the users the re-authenticate.
Device.openUri always sends the users to an auth page, which makes sense since i am not sending the token with it.
Is this possible at all? If so, How can it be done?
The short answer to exactly what you're asking is "no", and to what you are looking to achieve is "probably not". At least not today with MSAL directly.
When the user is sent off to sign in, MSAL is invoking a platform-dependent browser window which navigates to Azure AD for the sign-in and consent process. Depending on the device platform, this browser window may (or may not) share a cookie state with other apps and the full browser.
If it does share the cookie space, then the cookies set during the sign-in to your app can be re-used when you launch SharePoint in the browser, to provide a relatively seamless sign-in straight to SharePoint. If it does not, then there will be no existing browser session artifacts (i.e. cookies) that Azure AD can use to provide single sign-in.
For example, on iOS (Xamarin), MSAL for .NET will invoke SFSafariViewController. SFSafariViewController does not share cookie space with other apps or with the Safari browser.

Process LockedOut status with Kentor/Owin

I'm using the Kentor/SampleOwinApplication and I can successfully sign in and out from my Idp. Now I've made some tests with revoked users in the Asp.Net database. After successful federation signin and back into ExternalLoginCallback, SignInManager.ExternalSignInAsync returns LockedOut and I land on the revoke page.
The problem is I'm not signed in for Asp.Net but I'm still for my Idp, so if I try to log in again, I'm considered already signed I am redirected instantly back to my service without the chance to try to log with another user.
I understand I would need to log out from my IDP when in the LockedOut status but it seems hard to do with Kentor because specifically I'm not signed in on the Asp.net site!
Interesting border case!
What you should do is that when in the ExternalLoginCallback when you find out that you are locked out, you should kick of a federated logout by initiating a logout with the external identity as an argument. That will redirect the user to the Idp and invalidate the Idp session.
Note that this might have side effects if the user is already logged in to other services from the same Idp. Those other services will be logged out too.

Confirming user credentials in Facebook/Google OAuth2

Scenario: I have been developing a web application for management of small and medium-sized enterprises. Some time ago we used login and password authentication that were stored in our database. Nowadays when "everyone uses facebook" we moved to Facebook/Google OAuth2 authentication as well.
The problem is, there are some key operations that have to be especially secured (e.g. changing addresses, accessing clients' details). The best way to do this is I guess to ask users for retyping them credentials just before these risky operations are executed. But, since I use social authentication I can not confirm credentials anymore :(
Is there any way that I can force Facebook or other OAuth2 provider to re-ask users for credentials even they are already logged in?
I think this may be useful for someone.
I have found such a credentials confirmation implemented on https://www.airbnb.com but only for facebook.
AirBNB uses
https://www.facebook.com/login/reauth.php as an authentication url
Facebook re-authentication mechanism is described widely here:
https://developers.facebook.com/docs/facebook-login/reauthentication
For Google it is possible to force re-authentication by setting max_auth_age parameter to 0
No prompt for re-authentication with OAUth2. Why and how to force it?

The way of STS token storing after validation

I need additional clarification.
If I got correctly from this link Where Federation authentication token is saved [WIF STS]? and other general WIF-STS discussions, STS token is in default scenario stored in cookie in an browser. In my browser it is split in two cookies started with FedAuth. It is OK. If I understood good, cookie is created by WIF after STS token validation on RolePlayer application. If it is like that, then cookie is in RolePlayer application domain. When user hit RolePlayer2 application (that is in federation and in second domain) then how STS knows about that user, when it has not access to created cookie.
Could you clarify this to me please ?
Refer: AD FS 2.0: How to Use Fiddler Web Debugger to Analyze a WS-Federation Passive Sign-In
You'll see the MSIS* cookies are used for ADFS as opposed to the FedAuth cookies that are used for the application.
So you navigate to RolePlayer2, redirects to ADFS, sees you already have a cookie i.e. have authenticated and mints the FedAuth cookies for that domain/application without asking you to login.

Resources