9

I'm trying to deploy on production (AWS Elasticbeanstalk server) a simple asp net core project that use IdentityServer; my test project is basically the React.js template of Visual Studio 2019 with enabled authentication.

In development all works fine, but in production I have an error when a try to use the jwt token to authenticate to my api.

WWW-Authenticate: Bearer error="invalid_token", error_description="The issuer 'http://***.elasticbeanstalk.com' is invalid"

The access_token used is what was returned from the call

POST http://***.elasticbeanstalk.com/connect/token

The strange behavior is that the following request to

GET http://***.elasticbeanstalk.com/connect/userinfo

It correctly returns the user data, access_token is used here, so I think the token is correct.

Unfortunately, the request to my api fails with the error above.

My Startup.cs code is this:

   public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));

        services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
            .AddEntityFrameworkStores<ApplicationDbContext>();

        services.AddIdentityServer()
            .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();

        services.AddAuthentication()
            .AddIdentityServerJwt();

        services.AddControllersWithViews();
        services.AddRazorPages();

        // In production, the React files will be served from this directory
        services.AddSpaStaticFiles(configuration =>
        {
            configuration.RootPath = "ClientApp/build";
        });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
        }
        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.UseRouting();

        app.UseAuthentication();
        app.UseIdentityServer();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller}/{action=Index}/{id?}");
            endpoints.MapRazorPages();
        });

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

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

The appsetting.json file contains this:

    {
      "ConnectionStrings": {
        "DefaultConnection": "***"
      },
      "Logging": {
          "LogLevel": {
          "Default": "Information",
          "Microsoft": "Warning",
          "Microsoft.Hosting.Lifetime": "Information"
          }
        },
      "IdentityServer": {
        "Clients": {
          "myapp": {
            "Profile": "IdentityServerSPA",
            "RedirectUris": [ "/signin-oidc" ]
          }
        },
        "Key": {
          "Type": "Store",
          "StoreName": "My",
          "StoreLocation": "LocalMachine",
          "Name": "CN=http://***.elasticbeanstalk.com"
        }
      },
    "AllowedHosts": "*"
    }

blow
  • 12,811
  • 24
  • 75
  • 112

1 Answers1

14

In your startup set your domain's address

        services.AddIdentityServer(options =>
        {
            options.IssuerUri = "http://***.elasticbeanstalk.com";
        })
Mehrdad
  • 1,523
  • 9
  • 23
  • An alternative is to set the app up properly for sitting behind a load balancer. You need to use the X-Forwarded-For and X-Forwarded-Proto headers and update the current request context (assuming AWS does it the normal way) – mackie Mar 17 '20 at 10:34
  • 3
    This seems to be the correct solution but I don't understand why I need to set it. [Here](http://docs.identityserver.io/en/3.1.0/reference/options.html) they reccomend to not set this property because the value is inferred by the client request. – blow Mar 17 '20 at 20:28
  • 1
    To investigate the reason, and probebely find another way, decode your access_token's payload and see what is it's issuer. It'll help to find the reason of this error. – Mehrdad Mar 18 '20 at 03:15
  • 1
    @blow did you ever figure out why this was necessary despite the documentation saying otherwise? – Aviad P. Jun 14 '22 at 07:08
  • @mackie What if the token obtained by the client (on an HTTPS connection, with issuer `"https://example.com/identity"`) is then used by an internal service, that contacts `http://internal.host.name.local`? – Simone Sep 01 '23 at 14:54