0
votes

So, we have a SPA that is calling a series a microservices that sits behind an API Gateway. The authentication scheme is OpenId flow against Azure AD. So, it goes as follows: SPA (Public client) gets the access code, then the API gateway (Confidential Client) call the token service in order to get the access token; this is what it gets forwarded to the microservices themselves. So, in the end, our microservices will receive just the non-JWT Access Token. It's important to note that this token is NOT a JWT. In order to validate we're forced to use the /openId/UserInfo endpoint in the azure tenant to check the user with the access token.

We've tried used the AddOpenIdConnect extension in startup, as described [here] https://docs.microsoft.com/en-us/dotnet/architecture/microservices/secure-net-microservices-web-applications/

{
    //…
    // Configure the pipeline to use authentication
    app.UseAuthentication();
    //…
    app.UseMvc();
}

public void ConfigureServices(IServiceCollection services)
{
    var identityUrl = Configuration.GetValue<string>("IdentityUrl");
    var callBackUrl = Configuration.GetValue<string>("CallBackUrl");

    // Add Authentication services

    services.AddAuthentication(options =>
    {
        options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
    })
    .AddCookie()
    .AddOpenIdConnect(options =>
    {
        options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.Authority = identityUrl;
        options.SignedOutRedirectUri = callBackUrl;
        options.ClientSecret = "secret";
        options.SaveTokens = true;
        options.GetClaimsFromUserInfoEndpoint = true;
        options.RequireHttpsMetadata = false;
        options.Scope.Add("openid");
        options.Scope.Add("profile");
        options.Scope.Add("orders");
        options.Scope.Add("basket");
        options.Scope.Add("marketing");
        options.Scope.Add("locations");
        options.Scope.Add("webshoppingagg");
        options.Scope.Add("orders.signalrhub");
    });
}

But this assumes the whole OpenId flow. Regardless of putting the Bearer token in the request, application redirects to the login page.

So the question is, is there any out-of-the-box configuration for this? Or we should rely in some custom handler? In such case, how the user can be properly authenticated within the context? We would need to access the HttpContext.User.Claims in the controllers themselves.

Any hint would be greatly appreciated!

1

1 Answers

0
votes

Could I ask a couple of questions - partly for my own understanding:

  • What causes the token to not be a JWT - I don't think the link you posted explains this?
  • Are you using some form of token exchange from the original one issued to the SPA?

I have an equivalent solution that works, but I am using a free developer account, so maybe my setup is different:

If I understand how to reproduce your setup - and a rough understanding of the config differences - I may be able to help.

Using the user info endpoint to validate tokens doesn't feel right. It would be good to get token validation working in the standard way.