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
            });
        }

        }
2
  • 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 Commented Dec 25, 2019 at 8: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 Commented Dec 25, 2019 at 8:41

1 Answer 1

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
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot.I knew that I forgot something.That worked!
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.

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.