0
votes

I'm working on an Angular application that has an ASP.NET Core website for backend. Ie. based from the Angular .NET template. I'm also using Auth0.

Because I don't want the Angular HTML/Javascript to be available to anyone who isn't logged in, I've added authentication to both the server-side and the front-end.

So due to the serverside authentication - as soon as you visit the page for the first time, you immediate get redirected by the server-side to Auth0 to login, then you get redirected back to the site. This works fine.

Once logged in (server-side), the client-side then does the following in the app.component.ts constructor…

authService.isAuthenticated$.subscribe(value => {
    if (!value)
    authService.login()
})

Note that for the client-side, I've exactly followed these instructions: https://auth0.com/docs/quickstart/spa/angular2

So authservice in my above example, just uses the authservice from that Auth0 quick start page.

The idea behind the above snippet, is that if you get to this point, you've already signed in due to the server-side redirect, and the above ‘this.authService.login()' will only be called the first time, and will redirect to auth0 and immediately back again because you've already logged in to the auth0 identity provider. So this client-side redirect is just populating local browser-storage.

This works fine in Chrome (although, it does redirect to auth0 an additional time than I'd expect). In Firefox though, this continuously redirects back to auth0, back to my site, back to auth0, etc.

I'm guessing I'm approaching this problem in completely the wrong way! Could anyone advise on the best way to solve this issue?

I also tried doing the same, but using the authService.loggedIn property. But this then continuously redirects in both Chrome and Firefox!

2
So this means that authService.login() fails for some reason. I would check if handleAuthCallback() is reached, and if so, whether window.location.search includes an "error" property instead of the expected "code" property. - mcoomans
If you debug those three lines of code: what values brings 'value'? at every iteration? - Massimo Variolo
Sorry @mcoomans - only just seen your reply. Will take a look and debug them when I'm next on this project on Friday. Thanks for our help :) - Dan
@mcoomans No errors. Code and state are in the query string as expected when redirected back from Auth0 - Dan
@MassimoVariolo Sorry, I'm not sure what you mean by this. First time it hits the if statement, value is false (as expected), then the call to autoService.Login() redirects to Auth0, and back again, but the if statement is unexpectedly still false, so it tries to redirect again. - Dan

2 Answers

0
votes

You can check if 3-rd-party cookies allow in your browsers, I had infinite redirection in my project(with Auth0 authentication) because 3-rd-party cookies were blocked.

0
votes

Worked out how to do it...

this.authService.isAuthenticated$.subscribe(isAuthenticated => {
  if (isAuthenticated) {
    this.updateUserContextState()
  } else {
    if (window.location.search.includes('code=')) {
      // Because not authenticated, but code is in query string - wait for authService to redirect
      this.router.events.pipe(
        filter((e): e is NavigationEnd => e instanceof NavigationEnd)
      )
      .subscribe(x => {
        this.updateUserContextState()
      })
    } else {
      // Because not authenticated, and 'code' isn't in query string - start login. Because the
      // serverside MVC project has already done the Auth0 redirect, Auth0 should redirect straight
      // back to us with the code in the query string, then we'll hit the 'if' part of this 'else' statement.
      this.login()
    }
  }
})

Ignore the updateUserContextState function call. This is just a function which gets some info from my API once user is logged in to determine what the navbar should show. I basically want to call this on page load once I know the user is logged in. Ignore this bit though - the key bit is described below...

The infinite redirect would have been caused because when Auth0 redirects back to my site, I wasn't logged in at that point (because code is still in the query string, and the Auth0 library hasn't processed it yet). So in the new snippet above, you can see that I'm checking for code in the query string, then waiting for Auth0 to do the local redirect (removing the code from the query string). At that point I know the user is logged in and Auth0 has finished processing the login.