-3

I try to do central Authentication microservices using Identity server 4 and invoke another API microservices with Ocelot API gateway and all of them based on docker and docker-compose but always get unauthorize 401 Error with valid Access Token. this Question is also same as my problem what I had Ocelot Identity Server: message: Request for authenticated route {api-path} by was unauthenticated

Config.cs

  public static class Config
    {
        public static IEnumerable<ApiResource> ApiResources =>
    new ApiResource[]
    {
        new ApiResource("scope1")
        {
            Scopes = new List<string>{ "scope1"},
            ApiSecrets = new List<Secret>{ new Secret("supersecret".Sha256()) }
        }
    };
        public static IEnumerable<IdentityResource> IdentityResources =>
            new IdentityResource[]
            {
                new IdentityResources.OpenId(),
                new IdentityResources.Profile(),
            };

        public static IEnumerable<ApiScope> ApiScopes =>
            new ApiScope[]
            {
                new ApiScope("scope1"),
                new ApiScope("scope2"),
            };

        public static IEnumerable<Client> Clients =>
            new Client[]
            {
                // m2m client credentials flow client
                new Client
                {
                    ClientId = "m2m.client",
                    ClientName = "Client Credentials Client",

                    AllowedGrantTypes = GrantTypes.ClientCredentials,
                    ClientSecrets = { new Secret("511536EF-F270-4058-80CA-1C89C192F69A".Sha256()) },

                    AllowedScopes = { "scope1" }
                },

                // interactive client using code flow + pkce
                new Client
                {
                    ClientId = "interactive",
                    ClientSecrets = { new Secret("49C1A7E1-0C79-4A89-A3D6-A37998FB86B0".Sha256()) },

                    AllowedGrantTypes = GrantTypes.Code,

                    RedirectUris = { "https://localhost:44300/signin-oidc" },
                    FrontChannelLogoutUri = "https://localhost:44300/signout-oidc",
                    PostLogoutRedirectUris = { "https://localhost:44300/signout-callback-oidc" },

                    AllowOfflineAccess = true,
                    AllowedScopes = { "openid", "profile", "scope2" }
                },
            };
    }

and this is Startup

  public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
        //services.AddIdentityServer()
        //    .AddDeveloperSigningCredential()
        //    .AddInMemoryIdentityResources(Config.IdentityResources)
        //    .AddInMemoryApiScopes(Config.ApiScopes)
        //    .AddInMemoryClients(Config.Clients);
        var builder = services.AddIdentityServer(options =>
        {
            options.Events.RaiseErrorEvents = true;
            options.Events.RaiseInformationEvents = true;
            options.Events.RaiseFailureEvents = true;
            options.Events.RaiseSuccessEvents = true;

            // see https://identityserver4.readthedocs.io/en/latest/topics/resources.html
            options.EmitStaticAudienceClaim = true;
        })
            .AddTestUsers(TestUsers.Users);

        // in-memory, code config
        builder.AddInMemoryIdentityResources(Config.IdentityResources);
        builder.AddInMemoryApiScopes(Config.ApiScopes);
        builder.AddInMemoryClients(Config.Clients);
        builder.AddInMemoryApiResources(Config.ApiResources);

        // not recommended for production - you need to store your key material somewhere secure
        builder.AddDeveloperSigningCredential();

        services.AddAuthentication()
            .AddGoogle(options =>
            {
                options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;

                // register your IdentityServer with Google at https://console.developers.google.com
                // enable the Google+ API
                // set the redirect URI to https://localhost:5001/signin-google
                options.ClientId = "copy client ID from Google here";
                options.ClientSecret = "copy client secret from Google here";
            });
    }

    public void Configure(IApplicationBuilder app)
    {
        if (Environment.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        app.UseIdentityServer();
        app.UseStaticFiles();

        app.UseRouting();
       
        app.UseAuthorization();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapDefaultControllerRoute();
        });
    }

Api Microservice Startup.cs

services.AddAuthentication(
                options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

            }
            )
                .AddJwtBearer(options =>
            {
                IdentityModelEventSource.ShowPII = true;
                options.Authority = identityUrl;
                options.RequireHttpsMetadata = false;
                options.Audience = "scope1";
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidAudiences = new List<string>
                         {
                          "scope1"

                         }
                };


            });

Ocelot Statup.cs

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        var identityUrl = Configuration.GetValue<string>("IdentityUrl");
        var authenticationProviderKey = "IdentityApiKey";
        //…
        services.AddAuthentication()
            .AddJwtBearer(authenticationProviderKey, x =>
            {
               
                x.Authority = identityUrl;
                x.RequireHttpsMetadata = false;
               
                x.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
                {
                    ValidAudiences = new[] { "scope1" }
                };
            });

Ocelot.js

 {
      "RouteIsCaseSensitive": false,
      "DownstreamPathTemplate": "/api/inventory",
      "DownstreamScheme": "http",
      "DownstreamHostandPorts": [
        //  <-------------Local Host details ------------>
        {
          "Host": "inventoryservice",
          "Port": 80
        }
      ],

      "UpstreamPathTemplate": "/inventory",
      "UpstreamHttpMethod": [ "Get", "Post" ],
   
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "IdentityApiKey",
        "AllowedScopes": []
      }
    }

1 Answers1

0

I changed "ValidateIssuer" to False and everything worked fine after that.