Authentication Interceptor for Angular does not appear to work

To begin with, I apologise for any ignorance I show in this post I am very much a beginner to using Okta and Angular.

I have setup a very simple angular application and it is setup to do http get calls to a .net core web api, which is all working nicely. I then wanted to add authentication, which also appears to redirect to Okta correctly as well i.e. I cannot get to route I have set canActivate until redirected and logged in. So far so good.

However, my next step was to then also authenticate the .Net side so the http call will fail unless authenticated there as well. I used the Okta.AspNetCore package, set the following in ConfigureServices:

    services.AddCors(options =>
            {
                // The CORS policy is open for testing purposes. In a production application, you should 
restrict it to known origins.
                options.AddPolicy(
                    "AllowAll",
                    builder => builder.AllowAnyOrigin()
                                      .AllowAnyMethod()
                                      .AllowAnyHeader());
            });

            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = OktaDefaults.ApiAuthenticationScheme;
                options.DefaultChallengeScheme = OktaDefaults.ApiAuthenticationScheme;
                options.DefaultSignInScheme = OktaDefaults.ApiAuthenticationScheme;
            })
            .AddOktaWebApi(new OktaWebApiOptions()
            {
                OktaDomain = Configuration["Okta:OktaDomain"],
            });

And set the following in Configure:

app.UseCors("AllowAll");

        app.UseAuthentication();

        app.UseAuthorization();

Then I simply used the [Authorize] above the route in the controller (and of course correctly set my okta domain in appsettings accordingly).

This is unfortunately where I am stuck, the http request always returns a 401 whether logged into Okta or not. I assumed from following Okta tutorials this was because I needed the HttpInterceptor so added the following from one of these:

import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Observable, from } from 'rxjs';
import { OktaAuthService } from '@okta/okta-angular';
import { Injectable } from '@angular/core';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

  constructor(private oktaAuth: OktaAuthService) {
  }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
   return from(this.handleAccess(request, next));
  }

  private async handleAccess(request: HttpRequest<any>, next: HttpHandler): 
Promise<HttpEvent<any>> {
    // Only add an access token to whitelisted origins
    const allowedOrigins = ['http://localhost'];
    if (allowedOrigins.some(url => request.urlWithParams.includes(url))) {
      const accessToken = await this.oktaAuth.getAccessToken();
      request = request.clone({
        setHeaders: {
          Authorization: 'Bearer ' + accessToken
        }
      });
    }
    return next.handle(request).toPromise();
  }
}

And in App.Module:

import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { AuthInterceptor } from './auth.interceptor';

...
providers: [
{ provide: OKTA_CONFIG, useValue: oktaConfig },
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
   ],

This is supposed (I believe) to insert the bearer token into the api call, but I cannot find evidence of this in chrome developer tools or similar.

Am I missing something very obvious?

Hello,
There are a couple of Angular sample apps that show how to add the access token. Both the Custom and Okta hosted apps demonstrate this, look at the messages component.

The samples also contain a couple of .NET Core apps that demonstrate the resource server setup as well.

The interceptor code above is one of those samples as is the .Net code but it doesn’t appear to work which is why I am stuck.

Here’s how I’ve implemented the interceptor in OktaDev Schematics:

From https://github.com/oktadeveloper/schematics/blob/main/src/add-auth/angular/src/app/shared/okta/auth.interceptor.ts:

import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Observable, from } from 'rxjs';
import { OktaAuthService } from '@okta/okta-angular';
import { Injectable } from '@angular/core';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

  constructor(private oktaAuth: OktaAuthService) {
  }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return from(this.handleAccess(request, next));
  }

  private handleAccess(request: HttpRequest<any>, next: HttpHandler): Promise<HttpEvent<any>> {
    // Only add an access token to whitelisted origins
    const allowedOrigins = ['http://localhost'];
    if (allowedOrigins.some(url => request.urlWithParams.includes(url))) {
      const accessToken = this.oktaAuth.getAccessToken();
      request = request.clone({
        setHeaders: {
          Authorization: 'Bearer ' + accessToken
        }
      });
    }
    return next.handle(request).toPromise();
  }
}

From https://github.com/oktadeveloper/schematics/blob/main/src/add-auth/angular/src/app/auth-routing.module.ts:

providers: [
  { provide: OKTA_CONFIG, useValue: oktaConfig },
  { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
],

Are you trying to connect to a backend server that’s not on localhost?

No its on localhost, its a local asp.net web api project.
I believe my code posted matches yours as well

It is on https though silly me, missing an s. That resolved the bearer being in the request but still get a 401 response from the .net project. Works ok on an endpoint with no [Authorize] attribute so address is ok just not authenticating on the .net side for some reason.

Looking further into this I see the console has provided the following error:

Access to XMLHttpRequest at ‘https://localhost:44308/api/test/getdummydata’ from origin ‘http://localhost:4200’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

I have the CORS setup in Core (tried with AllowAllOrigins as well without AllowCredentials):

options.AddPolicy(
                "AllowAll",
                builder => builder.WithOrigins("http://localhost:4200")
                                  .AllowAnyMethod()
                                  .AllowAnyHeader()
                                  .AllowCredentials());

I have the app.UseCors(“AllowAll”); set and on relevant route testing I have [EnableCors(“AllowAll”)]

I’m sure I’m not missing anything compared to other examples