1

I trying to add identity server for my web API as its identity server4 documentation. when I was trying to call API from my console application it's every time returns InternalServerError.

Here is My Identity server Config.cs

public static class Config
{
    // register api
    public static IEnumerable<ApiScope> ApiScopes => new List<ApiScope>
   {
        // in here add your api name 
      new ApiScope("api1", "My API")
   };

    // register client which is going to access api. eg: front-end application, mobile apps etc. can add multiple client.
    public static IEnumerable<Client> Clients => new List<Client>
    {
      new Client
      {
          // which is going to access
          ClientId = "client",
          // no interactive user, use the clientid/secret for authentication
         AllowedGrantTypes = GrantTypes.ClientCredentials,
         // secret for authentication
        ClientSecrets =
        {
            new Secret("secret".Sha256())
        },

        // scopes that client has access to
        AllowedScopes = { "api1" }

      }
    };

}

and here the identity server startup file configuration service and configure functions

  public void ConfigureServices(IServiceCollection services)
        {
            // uncomment, if you want to add an MVC-based UI
            services.AddControllersWithViews();

            var builder = services.AddIdentityServer()
                .AddInMemoryApiScopes(Config.ApiScopes)
                .AddInMemoryClients(Config.Clients);

            builder.AddDeveloperSigningCredential();

          
            builder.AddDeveloperSigningCredential();
        }

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

            // uncomment if you want to add MVC
            app.UseStaticFiles();
            app.UseRouting();

            app.UseIdentityServer();

            // uncomment, if you want to add MVC
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapDefaultControllerRoute();
            });
        }

and here is my API startup file's congurationService and configure functions

 public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddAuthentication("Bearer")
                .AddJwtBearer("Bearer", options =>
                {
                    options.Authority = "https://localhost:14030/";
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateAudience = false
                    };
                }
                );
           
        }

        
   

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseHttpsRedirection();

        app.UseRouting();

        app.UseAuthentication();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }

here is my API controller

[Route("identity")]
  
    public class IdentityController : ControllerBase
    {
        [HttpGet]
        [Authorize]
        public IActionResult Get() => Ok(new JsonResult(from c in User.Claims select new { c.Type, c.Value }));
    }

and here is my console application client request a api

 static async System.Threading.Tasks.Task Main(string[] args)
        {

            // discover endpoints from metadata
            var client = new HttpClient();

            var disco = await client.GetDiscoveryDocumentAsync("http://localhost:14030");
            if (disco.IsError)
            {
                Console.WriteLine(disco.Error);
                return;
            }

            // request token
            var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
            {
                Address = disco.TokenEndpoint,
                ClientId = "client",
                ClientSecret = "secret",
                Scope = "api1"
            });

            if (tokenResponse.IsError)
            {
                Console.WriteLine(tokenResponse.Error);
                return;
            }

            Console.WriteLine(tokenResponse.Json);
            Console.WriteLine("\n\n");

            // call api
            var apiClient = new HttpClient();
            apiClient.SetBearerToken(tokenResponse.AccessToken);

            var response = await apiClient.GetAsync("https://localhost:5001/identity");
            if (!response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.StatusCode);
            }
            else
            {
                var content = await response.Content.ReadAsStringAsync();
                Console.WriteLine(content);
            }
        }

what are the mistakes should I have to fix. Im really appreciates your valuable answers and efforts.

Thank

0

1 Answer 1

1

I got the code working, I would do the following:

use HTTPS here, not HTTP:

var disco = await
   client.GetDiscoveryDocumentAsync("http://localhost:14030");

Remove the duplicate lines of in IdentityServer startup class:

builder.AddDeveloperSigningCredential();

I would add in your API startup.cs

services.AddAuthorization();

Remove the trailing / at the end of the URL here:

options.Authority = "https://localhost:14030/";

To get more debugging output from your API, you can add the following two trace lines to your appsettings.Development.json file:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information",
      "Microsoft.AspNetCore.Authentication": "Trace",
      "Microsoft.AspNetCore.Authorization": "Trace"
    }
  }
}

If you want to validate the Audience (and using IdentityServer4 v4.00) you can add:

services.AddControllers();

services.AddAuthentication("Bearer")
    .AddJwtBearer("Bearer", options =>
        {
            options.Authority = "https://localhost:14030";
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidAudiences = new[] {"https://localhost:14030/resources"},
                ValidateAudience = true
            };
        }
    );
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.