ASP Net Core IdentityServer, "The issuer is invalid" on production environment
Asked Answered
C

1

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": "*"
    }

Casemate answered 16/3, 2020 at 21:30 Comment(1)
Probably unrelated but should that not be HTTPS?Lug
L
14

In your startup set your domain's address

        services.AddIdentityServer(options =>
        {
            options.IssuerUri = "http://***.elasticbeanstalk.com";
        })
Lepus answered 17/3, 2020 at 4:5 Comment(5)
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)Lug
This seems to be the correct solution but I don't understand why I need to set it. Here they reccomend to not set this property because the value is inferred by the client request.Casemate
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.Lepus
@Casemate did you ever figure out why this was necessary despite the documentation saying otherwise?Solicitude
@Lug 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?Kidron

© 2022 - 2024 — McMap. All rights reserved.