0

I'm able to generate tokens succesfully when user login the app.But after I added [Authorize] on my controller,that token comes from header cannot pass the authorization.On Postman returns Unauthorized even though sending up-to date token in header to controller.Before added [Authorize] that worked very well

Startup.cs

      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.AddDbContext<DataContext>(x => x.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
        services.AddControllers().AddNewtonsoftJson(opt => {
            opt.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
        });
        services.AddCors();
        services.AddAutoMapper(typeof(AppointmentRepository).Assembly);
        services.AddScoped<IHospitalRepository, HospitalRepository>();
        services.AddScoped<IAppointmentRepository, AppointmentRepository>();
        services.AddScoped<IPatientRepository, PatientRepository>();

        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
   {
       options.TokenValidationParameters = new TokenValidationParameters
       {
           ValidateIssuerSigningKey = true,
           IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII
           .GetBytes(Configuration.GetSection("AppSettings:Token").Value)),
           ValidateIssuer = false,
           ValidateAudience = false
       };
   });
        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.UseCors(x => x.WithOrigins().AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());

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

login Method in controller

  [HttpPost("login")]

        public async Task<IActionResult> Login(PatientLoginDto patientLoginDto)
        {
            //if user exists or not
            var patientFromRepo = await _repo.Login(patientLoginDto.IdentityNumber, patientLoginDto.Password);

            if (patientFromRepo == null)
            { return Unauthorized(); }

            var claims = new[]
            {
                //Token has two claim username and id
                new Claim(ClaimTypes.NameIdentifier,patientFromRepo.Id.ToString()),
                new Claim(ClaimTypes.NameIdentifier,patientFromRepo.Name)
            };

            //key generated
            var key = new SymmetricSecurityKey(Encoding.UTF8
                .GetBytes(_config.GetSection("AppSettings:Token").Value));

            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature);

            var tokenDescriptor = new SecurityTokenDescriptor
            {
                //passing claims
                Subject = new ClaimsIdentity(claims),
                //expiry date in hours
                Expires = DateTime.Now.AddDays(1),
                SigningCredentials = creds
            };

            var tokenHandler = new JwtSecurityTokenHandler();

            //storing token here(based on token  descriptor object)
            var token = tokenHandler.CreateToken(tokenDescriptor);

            var patient = _mapper.Map<PatientLoggedinDto>(patientFromRepo);

            return Ok(new
            {
                //as response send back to the client
                token = tokenHandler.WriteToken(token),
                patient
            });
        }

        }
Timuçin Çiçek
  • 1,516
  • 3
  • 14
  • 39
  • 1
    1. Did you add `UseAuthentication()` ? 2. If you did, could you please include the Startup.cs? 3. What did you get when you say "cannot pass the authorization"? 4. It would be nice if you show us the payload – itminus Dec 25 '19 at 08:33
  • @itminus I've updated my startup.cs . Ass you can see I've added authorization already.I wish I could show you the playload but when I debug the controller which has [Authorize], it cannot pass that decorator. Seems like it doesn't recieve the token I pass through the header in Postman.I'm gonna add the screenshot of the response and error from postman – Timuçin Çiçek Dec 25 '19 at 08:41

1 Answers1

3

You need register the AuthenticationMiddleware before app.UseAuthorization();:

app.UseRouting();
app.UseAuthentication(); // add this line. NOTE The order is important.
app.UseAuthorization();
// ... other middlewares
itminus
  • 23,772
  • 2
  • 53
  • 88
  • Thanks a lot.I knew that I forgot something.That worked! – Timuçin Çiçek Dec 25 '19 at 08:46
  • 1
    Indeed, order of useAuthentification over UseAuthorization is very important ! End-points with [Authorize] attribute returned 401. Couple of hours lost, checking and rechecking with Postman, before noticing the inversion in a version of startup. – peter.cyc Jul 05 '20 at 12:04