ASP.NET Identity With React App Is Breaking On OAuth2 Callback
I have used the ASP.NET Core React project template to create a web application into which I've installed Identity Server 4. The React app takes care of all the user interaction, with the dotnet application used as an API only. I've integrated a Google OAuth2 authentication option using the
services.AddAuthentication().AddGoogle builder extension provided by
Microsoft.AspNetCore.Authentication. Finally, the whole thing is containerised and deployed to a Linux App Service on Azure.
Most of my code was ported from a previous version which was a very similar setup but in that case I'd added a custom React app to an existing ASP.NET application rather than start with the official React project template for dotnet. Back then everything worked well. But I'm facing problems with my new version when deployed to Azure. Here's a Fiddler trace to highlight the issue:
vault2 is a client of the identity service.
identity-azure is the Identity Server application. The flow this trace shows is as follows:
- User clicks Sign In on the Vault application
- Browser is redirected to the Identity application
- User clicks the Google button to initiate the OAuth2 flow
- User signs in with Google account
- User is redirected to the default callback URL (
This last step is where the problem is. You'll notice that you don't see the callback URL in the Fiddler trace, but instead you see a couple of other requests (e.g.
service-worker.js) which are clearly being made from the React app. So the
signin-google path is being handled by the browser's cached React app and not the server. The React app uses
react-router-redux to handle certain routes client-side, and of course
signin-google is not one of these so it appears to be returning an empty component.
As far as I can tell, all my ASP.NET routes (implemented using the
Route attribute to decorate controller action methods) are handled consistently by the server. However, the
signin-google route is implemented in the authentication middleware so as far as I know I don't have much control over it other than to change its path. Is there something I can do to force this to be handled server-side?
I should add that this behaviour is quite erratic. It seems that if my Google account is signed out then the above is observed, but if my account is already signed in then
signin-google returns the expected 302 status code and the OAuth2 flow continues successfully.
I finally worked out what was going on. At least, I think I have. I can't be certain because I've since broken the React UI out into an entirely separate application but I was observing a similar pattern there. There was even a clue in my original question! Turns out the breaking pages were actually being served from the React app's service worker. I discovered this because even after breaking the React app out under its own domain leaving my
identity-azure domain a pure ASP.NET Web API, requests for certain URLs under
identity-azure were still behaving the same and I eventually noticed they were reporting themselves as being served by
ServiceWorker on my browsers's Network tab. Example below.
As soon as I cleared the browsers application cache (in Chrome on Windows this was
F12 > Application > Clear storage > Clear site data with
Unregister service workers checked.
I'm not 100% sure what the solution would be if I'd left my React app in the same solution as the ASP.NET backend, but I presume it'd involve excluding specific URLs from service worker. I hope this helps someone in the future.
By the way, if you're thinking of building a fully decoupled UI for Identity Server 4, there's a great starter example here.
- → How to Fire Resize event after all images resize
- → URL routing requires /Home/Page?page=1 instead of /Home/Page/1
- → Getting right encoding from HTTPContext
- → How to create a site map using DNN and C#
- → I want integrate shopify into my mvc 4 c# application
- → Bootstrap Nav Collapse via Data Attributes Not Working
- → Shopify api updating variants returned error
- → ASP.NET C# SEO for each product on detail page on my ECOMMERCE site
- → SEO Meta Tags From Behind Code - C#
- → How to implement search with two terms for a collection?