Auth0 Home Blog Docs

.net core API error of "Invalid token" for second Auth0 development environment

Hi, I’m developing an SPA app (React) with a .NET core API backend. I’ve been using Auth0 for authentication successfully for some time. I wanted to deploy the pre-production app so I am following the recommendations here by creating a separate tenant for development (keeping the original tenant for production).

So, I’ve replicated the app and api in the (new) development tenant. In testing the new environment, the authentication part works fine. A user can sign in and Auth0 returns an access token. However, accessing the .net API fails with an invalid token error ( WWW-Authenticate: Bearer error=“invalid_token”, error_description=“The signature key was not found”).

Here’s the relevant portion of the .net code in Startup:

.AddJwtBearer(options =>
{
options.Authority = “https://myapp-dev.auth0.com/”;
// options.Authority = “https://myapp.auth0.com/”;

	options.Audience = "https://myapp.api.com" ;
	options.SaveToken = true;
});

I’ve kept the audience the same for both the prod env (old) and dev environment (new). To my understanding, the only change on the API side is changing the “Authority” value. I’ve commented out the value that works when using the prod env. And I’ve inspected the JWT and everything looks fine.

Am I missing something?

Thanks

Hi @mclark.properties,

Welcome to the Auth0 Community Forum!

This sounds like a misconfiguration of your tenants, like there is some unintended cross-over between the two. Can you take a look at this topic and see if it provides any insight?

Hope this helps!

Thanks,
Dan

Dan,

Thanks for your response. I agree it seems like some misconfig of tenants and specifically the API, but I have looked at it many times and can’t figure it out. Today, I deleted the app and API on the new tenant and re-created through the dashboard. Same problem.

I had looked at that post. In that case, they had an error which pulled the wrong settings in the API. I’ve hardcoded the authority and audience (as shown above) for testing, so that wouldn’t appear to be the problem.

I know I’m missing something, but I’m stumped as to what it is. Any help would be much appreciated.

Can you please DM me a HAR file so I can investigate further? I would like to see the token.

Hi Dan,

Wanted to make sure you received my message with the HAR file. Any insights?

Thanks much

@mclark.properties

Unfortunately I was not able to find anything from the HAR.

Can you post the code you use to set up Auth0 in your api, specifically where it is failing?

There’s nothing very exotic. (The code essentially duplicates the Auth0 QuickStart). For completeness, I’ve pasted in both the ConfigureServices and Configure methods in the startup file. In ConfigureServices, I simply comment out the authority option value that works when authenticating using the original tenant and add the value for the new tenant (which doesn’t work). The server side of the application returns a 401 unauthorized error for all server calls. It never hits the authorization code. This is what’s perplexing. The client side successfully authenticates through Auth0 for the new tenant and the JWT looks correct. It just won’t validate on the server side, which is why your comment about tenant configuration makes sense to me, but I don’t see anything wrong with the API setup in the Auth0 dashboard either. Thanks

      public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

            //... services added here for DI



            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            // Set authentication service for Auth0 
            services.AddAuthentication(options =>
                {
                    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                })
            .AddJwtBearer(options =>            
            {
                options.Authority = "https://rentclick-dev.auth0.com/";
                //options.Authority = "https://rentclick.auth0.com/";

                options.Audience = "https://rentclick.api.com";
                options.SaveToken = true;
            });
			
			services.AddAuthorization(options =>
            {
                
                //add various auth policies...
            });

            services.AddDbContext<RentClickDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("Default")));

            // In production, the React files will be served from this directory
            services.AddSpaStaticFiles(configuration =>
            {
                configuration.RootPath = "ClientApp/build";
            });
        }
		
		public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseSpaStaticFiles();

            app.UseAuthentication();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller}/{action=Index}/{id?}");
            });

            app.UseSpa(spa =>
            {
                spa.Options.SourcePath = "ClientApp";

                if (env.IsDevelopment())
                {
                    spa.UseReactDevelopmentServer(npmScript: "start");
                }
            });
        }

I can’t find anywhere else where you need to input the domain, so this should work. Can you try and reconfig, this time using appsettings.json instead of hard coding the api config settings?