I'm currently working on a web application that authenticates users through Azure AD via OpenID Connect. When an unauthenticated user hits the application, they are redirected to the Microsoft login page where they can input their AD credentials and login to the site. This is all good and working as expected.
The issue is that Azure AD Access Tokens only last for an hour, so if a user sits on a page for over an hour and then decides to continue working on that page (like say, make ajax calls within the page), nothing happens on the users' end (the page basically becomes unresponsive to server calls). If the user manually refreshes their page then their access is refreshed and they can continue using the application as normal, but this is obviously a problem when users have to refresh their pages every hour.
I've been looking online for solutions but I can't find anything concrete; most questions dealing with the issue address Web API calls, but I haven't found any solid information on how to deal with the issue when authenticating through the back-end (i.e authenticating with Azure AD through OpenID) while attempting to make front-end (i.e ajax) calls when the AD Access Token has expired.
Related
I have an application which has multiple frontend SPAs (mostly React). They allow the user to sign in if they want to access privileged features, but an unauthenticated user is still able to access the site. Each SPA will access some backend apis using a token if they are authenticated. All of these sites should function transparently when it comes to login, so if you login on one site, it should be automatically propagated to all the sites (SSO)
When a site first loads we want to get the token for the user if they are logged in with SSO. If we use the redirect flow and the user isn't signed in we will end up on the sign in page, which isn't what we want as we allow anonymous access. We only want to show the login page if the user explicitly clicks the login link on a site.
Is there a way to check if the user is logged into sso without redirecting to the login page?
We have looked at ssoSilent (from msal) which functionally does what we want however its only supported via third party cookies which don't work in some browsers.
I have thought perhaps we could redirect to a silent login page which if the user isn't logged in will just redirect back with an anonymous flag in the queryString, but I don't know if theres a way to do this with azure b2c.
The only method is ssoSilent(), or your own implementation of it via iframe. It should work as long as your app is on the same root domain as the AAD B2C login page, which you can do with the Custom Domain feature.
There is no API endpoint available to do what you want.
A customer changed to Azure AD, so we have to update our app accordingly. Unfortunately we don't have either access to the customers's Azure AD administration portal, nor do we have user credentials to test our app. We only know that ...
All starts here: https://myapplications.microsoft.com
Browser login consists of (1. dialog) email address, (2. dialog) password, (3. dialog) OTP token entry (OTP sent via SMS). Microsoft Authenticator works as well.
When through the authentication process, the page with the Azure applications appears. In our app, we'd like to avoid this page showing up, since the app should take over after the OTP token is entered in Microsoft Graph API (= authentication is completed). So authentication webview should close by itself after authentication is finished.
We read a lot about MSAL the last days, but since we have to code blindly (no sample login credentials/OTP available, no Azure AD administration access), it's kind of fishing in the dark.
We used this page as starting point: https://github.com/AzureAD/microsoft-authentication-library-for-objc
We use Xcode 13.4.1 with Swift.
By using Safari Web Inspector on the concerned Azure AD application, we populated the required MSAL constants as follows:
let kClientID = "2793995e-0a7d-40d7-bd35-6968ba142197" // probably not correct, see (a.) below
let kGraphEndpoint = "https://graph.microsoft.com/" // not found in Web Inspector data, but most MSAL code uses it
let kAuthority = "https://login.microsoftonline.com/common/" // found in Web Inspector data
let kRedirectUri = "https://myapplications.microsoft.com" // the URL after authentication is complete
let kScopes: [String] = ["User.Read"] // not found in Web Inspector data, but most MSAL code uses it
Questions/Problems:
https://myapplications.microsoft.com always shows the client_id 2793995e-0a7d-40d7-bd35-6968ba142197. As far as we understood, every Azure AD application has it's own client_id, hence 2793... cannot be correct since it's "generic". If the client_id is not correct, can we find the correct one using the concerned Azure AD application Safari Web Inspector data?
Above constants seem to work, but when our testers login, the last page showing all Azure AD applications remains open. Some sample MSAL test code from Github however close Microsoft Graph API after credentials were entered. Is this closure of the authentication webview triggered by the server (Azure AD setting) or the client?
After testers logged in through the app, then suspended the app (via App Switcher), then opened the app again - the complete Graph API login was required again. Silent login (aquireTokenSilently) didn't work. When using Safari, silent login works however. What could be wrong?
Does the Safari Web Inspector data tell us what the product bundle identifer is (which we need for msauth.$(PRODUCT_BUNDLE_IDENTIFIER) as redirect URI)?
So basically, we'd like to ...
avoid the Graph API portal page, which shows up after authentication is done
remain logged in after app returns from suspended (acquireTokenSilently())
use Authenticator if installed on the device
We've never worked with Azure AD before.
Any hint about mistakes/misunderstandings would help.
Many thanks!
----- UPDATE (27.07.2022) -----
As a reminder ... we neither have access to the Azure AD portal, nor do we have test credentials (username, password, SMS code [OTP]).
After lots of testing and simulating, still no success.
Using Safari, the flow for a regular user looks like this:
https://myapplications.microsoft.com
The authentication starts with the entry of the organization specific email address.
Azure detects this organization, checks the existence of the email address and asks fro the password.
Next, Azure either sends an SMS code or triggers the broker (Microsoft Authenticator). It's device configuration specific which one is used.
The page with the Azure AD applications opens.
On iOS/macOS (Xcode, our application), the above flow is similar. MSAL debug messages reveal however that no token is sent. acquireToken() only completes after the webview is cancelled (MSAL error -50005). It seems that a Web application doesn't require a token ?!
Now ... in our (iOS) app, we only would like to get the token in order to access the Web application with our (iOS) app (using the Bearer inside the URL request).
How can we get a token for an Web application without redirecting to that page at the same time (which doesn't return a token)?
Does Azure AD allow access to that Web application using the gained token?
A server side (Azure AD) solution would be an redirect_uri entry in the Authentication section (MY_BUNDLE_ID). But we have to do without.
You don't need to target the MyApps app (2793995e-0a7d-40d7-bd35-6968ba142197). You should target your own Azure AD App registration. For more information please take a look to MSAL iOS Swift Microsoft Graph API Sample.
We are using Azure B2C for couple of our web applications. User could be using M365 Authentication or local account to login into our web applications via Azure B2C. Generally the authentication with Azure B2C works well although from time to time, we are running into the issue that end user could not login. With M365 account, end user would get a white page with bad request message there. For local account, end user just enters credential and clicks login and nothing happens. Here is the bad request screen shot:
From investigation, we found out that they have 2 browser tabs with same azure b2c login session since they clicked on our applications at different time and leave those tabs there. It doesn't happen very often, however once it happens, unfortunately this is a very bad experience for end users and there are no proper error messages or instructions for what end users should do next and they stuck without being able to move forward. Anything we could do here to improve this experience? Or better, could Azure B2C add some enhancement to make this experience better since M365 login itself seems handling this scenario much better. Thanks in advance.
I have created azure ad b2c custom sign-in policy with KMSI(keep me sign in) option, and using it in blazor server application,
But automatic sign in not working after browser close, Need to click 'Login' button.
After click login button no need to enter credential again, if at the time of previous sign-in KMSI check box checked.
But I want to sign-in automatically if at the time of sign in KMSI check box checked.
Could you check the authorization request the app sends to Azure AD B2C, whether it contains the prompt=login query string parameter? If yes, please make sure to remove this param.
This is expected, your app cookie is not persisted, so the app has no idea you’re still logged in at B2C. Therefore you have to click login in the app and then you get SSO through AAD B2C.
You could maintain a cookie set by the app to automatically send the user via the login endpoint if they had signed in previously with KMSI. You can use a claims resolver to send the KMSI claim into the token so your app can understand the user logged in with KMSI.
https://learn.microsoft.com/en-us/azure/active-directory-b2c/claim-resolver-overview
I tested KMSI functionality on my side, and I can repro your symptom. My test is based on this demo: https://github.com/Azure-Samples/active-directory-b2c-dotnet-webapp-and-webapi
This is my test process below:
Registering a local account.
Login by this account, and enabled KMSI
I logged in successfully:
Close the browser, reopen it and got to my app index, my index page is allowed to be visited by anonymous, so it not knows who am I: I think this is the issue that you are concerned about:
But when I click “Claims” tag which users are needed to be authenticated, it redirected to my b2c domain :
As I enabled KMSI, so there is a cookie under my b2c domain:
As this cookie exists, B2C will provide me with the resource I requested for: b2c side sends a request to redirect URL with id token and code :
Finally, it redirected to “Claim” page and this app knows who am I :
In a word, there are two kinds of sessions here: a session between user and B2C and a session between the user and your application.
Once you close your browser, by default, you will lose the cookie that user on your application, so users access to some page with no auth needed of your app after reopening the browser, there will be no cookie, your application not know the user. But on the B2C side, this cookie will be persisted there due to KMSI. Only users request some functionality needs to be authenticated on your app, users will be redirected to the B2C domain and B2C will send users’ information to your app will make KMSI work.
In my opinion, maybe extending the lifetime of your application cookie will be a solution here. At the same time, you also need to expand session timeout to make sure that your application could recognize that long lifetime cookie. But as we know, it will be a high consumption for server RAM if it holds lots of sessions.
We have a web application implemented in Java/JSP and Azure AD single-sign-on authentication has been implemented using OpenID connect protocal. And the sign-in approach is working as expected, but the major issue is with sing-out. While signing out the user we are following the below approach.
1) User clicks sign-out button.
2) He will be redirected to application application sign-out page.
3) Clear the application session in sign-out page.
4) Then redirecting the user to Azure AD logout page, see below URL...
https://login.microsoftonline.com/common/oauth2/v2.0/logout?
post_logout_redirect_uri=our_application_sign_out_success_page
The above approach is working as expected, but the problem is, if user copy and paste above URL in the browser tab when the user have a valid session in another browser tab, his AD session is getting cleared.
But the expected behavior is, the logout should happen only when user clicks the sign_out button.
This is expected behavior, the server is not able to detect whether the request is sent from clicking or paste in the address bar and navigate manually. And the server should'n care where is the request from, it only do the job you told it.
And if you have other applications also using the Azure AD as the identity data provider, the sign-out request will not affect the other applications when you sign-out from your web application. Also if you want to implement the single sign-out, you have to implement LogoutUrl in the web application and register it on the Azure portal.(refer here)