1
votes

I'm building a React app where I want to authenticate the user using OpenID Connect. In my dev environment the OIDC authority is a locally running instance of Identity Server 4.

I found a Github repo which integrates the oidc-client-js library with Redux so I downloaded the example repo and pointed it at my Identity Server. The only other change I made was to call a local API with my bearer token instead of the YouTube one used by the sample.

I have a Windows environment.

On Chrome and Edge the example works perfectly. I am able to authenticate and successfully call my local API using the bearer token. However, on Firefox, although the authentication works correctly and my API gets called successfully with results displayed, after a few seconds the app suddenly appears to sign the user out. (I say 'appears' because it behaves as though the user has been signed out but if I reload the page, the user is already authenticated).


Note: I've crossed out a section here. This was a red herring. See Update 1 below which describes how Firefox is adding a second iframe. A redirect URL wasn't registered for my client causing a redirect to IS4's error page which was responsible for these CSP warnings.

Looking at the console logs, a key difference between Chrome and Firefox is a warning I'm seeing in Firefox:

Content Security Policy: Ignoring ‘x-frame-options’ because of ‘frame-ancestors’ directive.

This appears in the console a second or two after authenticating the user. I suspect this might be related to the iframe the Javascript OIDC client adds for checking the session. This iframe points at /connect/checksession on the identity authority.

If I navigate to this checksession URL in Firefox I get a Javascript error in the console:

Content Security Policy: The page's settings blocked the loading of a resource at self ("script-src").

I don't see this error in Chrome.

The Content-Security-Policy for this page is default-src 'none'; script-src 'sha256-VDXN0nOpFPQ102CIVz+eimHA5e+wTeoUUQj5ZYbtn8w='


The only other bit of info I can provide is the console logs that are written as Firefox appears to sign the user out:

Action type: redux-oidc/USER_SIGNED_OUT 
Action payload: undefined
State before: Object { routing: {…}, oidc: {…}, subscriptions: {…} }
State after: Object { routing: {…}, oidc: {…}, subscriptions: {…} }

I'm hoping someone might be able to use this information to point me in the right direction because I'm really not sure what the problem is here. It seems the issue is within the Identity Server since it's reporting that Javascript error in Firefox on checksession, but I'm not sure what I can do about this.


UPDATE 1

Having delved deeper I've found the issue occurs when a second iframe gets added to the page calling the identity authority's connect/authorize endpoint with a URL like this: http://identity.domain.com/connect/authorize?client_id=js&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fsilent_renew.html&response_type=id_token&scope=openid&state=9d87c43c58c84fddbde5fd9aa0f97df7&nonce=826fb8d6dc114549810584ddd01a3271&prompt=none. This only happens with Firefox. In Chrome and Edge this second iframe never gets added. Looking at the Identity Server logs I see the followings lines (amongst others) logged during the response to this connect/authorize call:

No user present in authorize request

Showing error: prompt=none was requested but user is not authenticated".

But I'm still no closer to understanding why this is happening.

2

2 Answers

0
votes

I was seeing this behaviour intermittently in Chrome when using oidc-client-js directly. In my case adding a call to clearStaleState on the UserManager seemed to stop this from happening. EDIT: Specifically I added it before the call to getUser().

But since it was intermittent, it'd go away for a time if you logged out and cleared cookies and local/session storage, I can't guarantee this will fix it.

0
votes

Months later and I encountered this issue again. This time I worked out what the problem was. I was hosting my identity server locally on a non-localhost domain, but my React app was running on localhost. Therefore Firefox tracking protection was kicking in and blocking the Javascript OIDC client from accessing cookies on my identity server via its iframe. Switching to using identity server on a localhost port resolved the issue. I hope this helps someone :)