jeroenheijmans/sample-angular-oauth2-oidc-with-auth-guards

Microsoft Azure AD takes longer time on initial load with same setup

jeserkin opened this issue · 6 comments

For some reason, if I change scope, issuer and clientId in AuthConfig, then loading takes (I timed) ~5sec as in Initializing message is blinking for 5 seconds. Happens only while user is not signed in. After sign in is done, refreshing page loads it in expected time frame.

Also with Microsoft Azure AD it shows, that it is attempting to redirect to external link
image

ClientID: a3db960c-852a-4a0b-9b45-cb939562eee2
TenantID: 2d044a19-492e-4609-ab23-1a183a41dfe3
https://login.microsoftonline.com/2d044a19-492e-4609-ab23-1a183a41dfe3/oauth2/v2.0/authorize?response_type=code&client_id=a3db960c-852a-4a0b-9b45-cb939562eee2&state=Z0xidXNpbkMxcWx6VmJHQU5TYmNRR3I1R3BrbEZHVnFlNGwxRDZ0T25NekVv&redirect_uri=http%3A%2F%2Flocalhost%3A4200%2Fsilent-refresh.html&scope=openid%20api%3A%2F%2Fa3db960c-852a-4a0b-9b45-cb939562eee2%2Fapp&code_challenge=wainyA2LBDvc7Lvjpvus9DuZ0Kk5a05Zt1jhYDMAgHk&code_challenge_method=S256&nonce=Z0xidXNpbkMxcWx6VmJHQU5TYmNRR3I1R3BrbEZHVnFlNGwxRDZ0T25NekVv&prompt=none&iframe-request-id=95cd23ee-00a2-4e02-9e9f-881319050400

Heya, thanks for sharing this specific scenario!

Without the exact code or precise instructions to reproduce this scenario, it'll fall on yourself to debug this and share what the solution to this situation is. Did you try to debug and investigate what's going on?

I'm not sure if this would really be an issue with the sample repo and something we'd need to keep open here, or whether it's a peculiarity of that specific identity server solution?

One guess would be that the iframe in use for silent refreshes isn't allowing the redirect flow, e.g. because the X-FRAME-OPTIONS and related headers don't allow iframing the IDS? But it's just that: a guess. We'd need a repro or need you to check it out for us and let us know.

Did you try to debug and investigate what's going on?

Only as far as looking at network tab and that there was no pending request, that would influence load time. I glanced over library and didn't see any delays there as well. So I am not sure what is happening there.

I'm not sure if this would really be an issue with the sample repo and something we'd need to keep open here, or whether it's a peculiarity of that specific identity server solution?

That identity server is what portal.azure.com provides. Nothing custom. As one can see it from the url here.

We'd need a repro or need you to check it out for us and let us know.

I can check, but I need detailed explanation of what exactly I am checking for and where.

By a "repro" I mean "what are the steps one would need to take after git clone of this sample to see the behavior you describe?".

Or maybe I should first ask what your expectation is for this sample repository and the issue you describe? It is my aim with this repository to show working front-end code of how I would do things, and showcase that with one specific demo identity server (Duende, in this case). It's not my aim for it to be a comprehensive resource for all the various possible Identity Servers.

If you have a suggestion on how to improve this sample in a way that would also make another IDS like Azure AD work out of the box, that's highly welcome! If you want the community to help find out if the sample can be strengthened, we'd need a super easy way to reproduce the scenario. (Even then, it might be an implementation issue with that specific IDS, for which there's not much bandwidth here to help out with.)

Hope that makes sense!?

By a "repro" I mean "what are the steps one would need to take after git clone of this sample to see the behavior you describe?".

All I have done is change issuer, clientId and scope.

Also I think I had to add those 2 properties:

strictDiscoveryDocumentValidation: false,
requireHttps: false

I debugged a bit further and without silentRefresh capabilities it works much faster, BUT if I open separate tab (besides one where I am signed in) the session storage is empty in that new tab and I am not signed in there.

Or maybe I should first ask what your expectation is for this sample repository and the issue you describe?

Honestly, I was just looking for an explanation on how to construct flow with use of underlying library, so that I communicate with Azure AD. I do not expect for this sample to solve all world problems. As an example this sample I do not think would work with GitHub OAuth (but not 100% sure).

If you have a suggestion on how to improve this sample in a way that would also make another IDS like Azure AD work out of the box, that's highly welcome! If you want the community to help find out if the sample can be strengthened, we'd need a super easy way to reproduce the scenario. (Even then, it might be an implementation issue with that specific IDS, for which there's not much bandwidth here to help out with.)
Hope that makes sense!?

I did participate in one other Open Source project and I am all for making thing better, but I probably need more experience and understanding of OAuth, different authentication protocols, etc. before I can be of any meaningful help with improving something, that is related to it.

I had to configure a few extra things based on all comments above to reproduce the issue in Chrome on Windows. Here's a git diff from current main to see what's going on:

 export const authConfig: AuthConfig = {
-  issuer: 'https://demo.duendesoftware.com',
-  clientId: 'interactive.public', // The "Auth Code + PKCE" client
+  issuer: 'https://login.microsoftonline.com/2d044a19-492e-4609-ab23-1a183a41dfe3/',
+  clientId: 'a3db960c-852a-4a0b-9b45-cb939562eee2',
+  strictDiscoveryDocumentValidation: false,
+  skipIssuerCheck: true,
+  requireHttps: false,
   responseType: 'code',
   redirectUri: window.location.origin + '/',
   silentRefreshRedirectUri: window.location.origin + '/silent-refresh.html',
-  scope: 'openid profile email api', // Ask offline_access to support refresh token refreshes
+  scope: 'openid profile email', // Ask offline_access to support refresh token refreshes
   useSilentRefresh: true, // Needed for Code Flow to suggest using iframe-based refreshes
   silentRefreshTimeout: 5000, // For faster testing
   timeoutFactor: 0.25, // For faster testing

I run this with npm run start-with-ssl.

If you run with that you will see in Chrome on Windows after the 5ish second delay and then nothing. The console will yell at you:

Unsafe attempt to initiate navigation for frame with origin 'https://localhost:4200' from frame with URL 'https://login.microsoftonline.com/2d044a19-492e-4609-ab23-1a183a41dfe3/oauth2/authorize?response_type=code&client_id=a3db960c-852a-4a0b-9b45-cb939562eee2&state=MHkxWDBRbUlLS3Y1eVotTS5uaHJZNkJ4cXYtQUVKSmQxOTBIaFM4VXBOUUxE&redirect_uri=https%3A%2F%2Flocalhost%3A4200%2Fsilent-refresh.html&scope=openid%20profile%20email&code_challenge=b_5viMFmIj8uPOrUyyjfsQcYj8JPkaxuIhzjkJCtRLM&code_challenge_method=S256&nonce=MHkxWDBRbUlLS3Y1eVotTS5uaHJZNkJ4cXYtQUVKSmQxOTBIaFM4VXBOUUxE&prompt=none'. The frame attempting navigation is targeting its top-level window, but is neither same-origin with its target nor has it received a user gesture. See https://www.chromestatus.com/feature/5851021045661696.

If you use Firefox on Windows a different error furhter hints at the problem:

Sign in

Sorry, but we’re having trouble signing you in.
AADSTS50058: A silent sign-in request was sent but no user is signed in. The cookies used to represent the user's session were not sent in the request to Azure AD. This can happen if the user is using Internet Explorer or Edge, and the web app sending the silent sign-in request is in different IE security zone than the Azure AD endpoint (login.microsoftonline.com).

That strongly suggests to me that this code from the sample:

// 2. SILENT LOGIN:
// Try to log in via a refresh because then we can prevent
// needing to redirect the user:
return this.oauthService.silentRefresh()
.then(() => Promise.resolve())
.catch(result => {

will not work with this particular Identity Provider.

You will need to switch to using refresh tokens, not use said part of the sample, or find a way to reconfigure Azure AD to support this scenario.

It's weird to me, because their docs suggest prompt=none logins (silent logins) are supported but if you have to know beforehand whether it will succeed, that kind of defeats the purpose?

I hope that helps. Recommend looking for further support from the Azure AD side of things, don't think we'll change much here on this sample unfortunately. Hope that makes sense?

Huge thank you.