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?