Home > Blockchain >  ASP.NET Can't Implement Authentication/Authorization
ASP.NET Can't Implement Authentication/Authorization

Time:12-22

I am trying to create a basic WebApp in .NET 5 using Identity. I implemented Database, Repos, API, etc., and Identity(extended) without a problem. Now, I want to implement a login system using cookies and IdentityRole.

I am using signInManager.PasswordSignIn to sign in the user and I got a cookie without a problem. But when I try to request an Authorized call from the controller I am redirected to the login path even though the user has the role specified in the [Authorize] annotation.

Here you can see the cookie I get after requesting signin and I can get all users because there is no [Authorize] annotation on that request.

SignIn Response

Identity Cookie

But when I try to access a specific user I get 401 because GetUser(id) has [Authorize(Roles = "User")] as an annotation even though my user has a "User" role.

401 on GET

AspNetRoles Table

AspNetUserRoles Table

Id of FirstUser and UserId in UserRoles matches, so I am not logged in on wrong user

What am I doing wrong?

Startup.cs

//ConfigureServices
services.AddIdentity<User, IdentityRole>(config => {
    config.SignIn.RequireConfirmedEmail = false;
})
  .AddEntityFrameworkStores<FoodDonationContext>()
  .AddDefaultTokenProviders();

services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
{
    builder.WithOrigins("http://localhost:3000")
    .AllowAnyMethod()
    .AllowAnyHeader()
    .AllowCredentials();
}));
            
services.ConfigureApplicationCookie(options =>
{
    options.AccessDeniedPath = "/TEST1"; //These TEST redirections are for debbugging
    options.Cookie.HttpOnly = true;
    options.ExpireTimeSpan = new TimeSpan(1, 0, 0);
    options.LoginPath = "/TEST2";
    options.LogoutPath = "/TEST3";
    options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
    options.SlidingExpiration = true;
    options.Events.OnRedirectToLogin = context =>
    {
        context.Response.StatusCode = StatusCodes.Status401Unauthorized;
        return Task.CompletedTask;
    };
});

//Configure
app.UseRouting();
app.UseHttpsRedirection();
app.UseCors("MyPolicy");
            

app.UseCookiePolicy(new CookiePolicyOptions
{
    Secure = CookieSecurePolicy.None
});

app.UseAuthorization();
app.UseAuthentication();

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

UserController.cs

[Route("api/[controller]")]
[ApiController]
public class UserController : Controller
{
    private readonly IUserRepo _repository;
    private readonly IMapper _mapper;
    private readonly UserManager<User> _userManager;
    private readonly SignInManager<User> _signInManager;

    public UserController(IUserRepo repository, IMapper mapper, UserManager<User> userManager, SignInManager<User> signInManager)
    {
        _repository = repository;
        _mapper = mapper;
        _userManager = userManager;
        _signInManager = signInManager;
    }

    [HttpPost("signin")]
    public async Task<ActionResult> SignInUser(UserSignInDTO signInData)
    {
        var user = await _repository.GetUserWithUserNameAsync(signInData.UserName);
        if (user != null)
        {
            var result = await _signInManager.PasswordSignInAsync(user, signInData.Password, false, false);
            if (result.Succeeded)
            {
                RedirectToRoute("/TEST5");
                return Ok(result);
            }
            else
                return BadRequest();
            }

        return NotFound();
    }

    [Authorize(Roles = "User")]
    [HttpGet("{id}", Name = "GetUser")]
    public async Task<ActionResult<UserReadDTO>> GetUser(string id)
    {
        var user = await _repository.GetUserAsync(id);
        if (user != null)
        {
            user.Age = DateTime.Now.Subtract(user.BirthdayDate).Days / 365;
            _repository.SaveChangesAsync();

            return Ok(_mapper.Map<UserReadDTO>(user));
        }
            return NotFound();
        }

    [HttpGet(Name = "GetAllUsers")]
    public async Task<ActionResult<IEnumerable<UserReadDTO>>> GetAllUsers()
    {
        var userList = await _repository.GetAllUsersAsync();
        if (userList != null)
        {
            foreach (var user in userList) {
                user.Age = DateTime.Now.Subtract(user.BirthdayDate).Days / 365;
            }
        _repository.SaveChangesAsync();

        return Ok(_mapper.Map<IEnumerable<UserReadDTO>>(userList));
       }
       return NotFound();
    }
}

CodePudding user response:

app.UseAuthorization();
app.UseAuthentication();

It worked when I changed the order of these two.

  • Related