lonelydev101
lonelydev101

Reputation: 1901

.net core 5.0.2 and jwt => response 401 Unauthorized

I am following an video tutorial for identity server 4 with web api's. And Im not sure when I went wrong.

Im getting 401 Unauthorized when I try to call api with bearer token. In previos step, without authorization, my api worked.

This is my api controller in my TablesReach.API project:

...
namespace TablesReach.Controllers
{
    [Authorize]
    [Route("api/[controller]")]
    [ApiController]
    public class UsersController : ControllerBase
    {
        private readonly DataContext _context;

        public UsersController(DataContext context)
        {
            _context = context;
        }

        // GET: api/Users
        [HttpGet]
        public async Task<ActionResult<IEnumerable<User>>> GetUsers()
        {
            return await _context.Users.ToListAsync();
        }
...

this is my Startup.cs of my api project:

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddAuthentication("Bearer")
                .AddIdentityServerAuthentication(opts => 
                { 
                    opts.Authority = "http://localhost:5000";
                    opts.RequireHttpsMetadata = false;
                    opts.ApiName = "TablesReachApi";
                });

            services.AddDbContext<DataContext>(opts => opts.UseInMemoryDatabase("UNWDb"));

            services.AddControllers();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

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

            app.UseAuthentication();
        }
    }

My other project TablesReach.IdentityServer is host on localhost:5000 and Im being able to get bearer token, so I assume that this project is quite OK. identityServer startup.cs class:

 public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddIdentityServer()
                .AddDeveloperSigningCredential()
                .AddInMemoryApiScopes(Config.GetAllApiResources())
                .AddInMemoryClients(Config.GetClients());
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            //else
            //{
            //    app.UseExceptionHandler("/Home/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.UseRouting();

            //app.UseAuthorization();

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

            app.UseIdentityServer();

        }
    }

and Config.cs:

public class Config
    {
        public static IEnumerable<ApiScope> GetAllApiResources()
        {
            return new List<ApiScope>
            {
                new ApiScope("TablesReachApi", "Api for solution")
            };
        }

        public static IEnumerable<Client> GetClients()
        {
            return new List<Client>
            {
                new Client
                {
                    ClientId = "client",
                    AllowedGrantTypes = GrantTypes.ClientCredentials,
                    ClientSecrets =
                    {
                        new Secret("secret".Sha256())
                    },
                    AllowedScopes = { "TablesReachApi" }
                }
            };
        }
    }

Note: When I remove annotation [Authorize] from my api controller I can reach my method.

Upvotes: 0

Views: 78

Answers (1)

Dennis VW
Dennis VW

Reputation: 3177

For some middleware, order matters. Authentication and authorization, for example, can't go in the order that you have put them in the API. Microsoft has some clear documentation on this for you to read here..

Upvotes: 1

Related Questions