Using .NET Cookie Authentication for anonymous/temporary users

127 Views Asked by At

I have a react app & .NET Web Api and I want to add some layer of authentication and authorization on the Api.

Scenario

User completes a registration form in the react app which will not create an account, but will allow the user to move to the next page where he can fill other forms and download pdfs. Only using some features like persist changes will require an account.

With these requirements what I got so far.

  1. Setup Authentication and authorization on the API side, when user POST then a cookie will be generated
  2. Use [Authorize] on routes where don't allow users that didn't fill the form

Setup that I have so far

      const onRegisterFormFinish = (values: any) => {

    fetch(`${REACT_APP_API_URL}/register`, {
      method: "POST",
      body: JSON.stringify(values),
      credentials: "include",
      headers: {
        "Content-Type": "application/json",
      },
    })
      .then((response) => {STORE some indetificatior in LocalStorage for guarded routes})
      .catch(...)
      .finally(...);
  };

Web Api Program.cs setup

  builder.Services.AddCors(crs =>
{
    crs.AddPolicy("All", cfg =>
    {
        cfg.AllowAnyHeader();
        cfg.AllowAnyMethod();
        cfg.WithOrigins("http://localhost:3000");
        cfg.AllowCredentials();

    });
});
builder.Services
    .AddAuthentication(opt =>
    {
        opt.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        opt.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    })
    .AddCookie(opt =>
    {
        opt.Cookie.IsEssential = true;
        opt.Events.OnRedirectToLogin = context =>
        {
            context.Response.StatusCode = StatusCodes.Status401Unauthorized;
            return Task.CompletedTask;
        };
    })
    ;
builder.Services.AddAuthorization();

And the Controller action that does the authentication :

[HttpPost]
public async Task<IActionResult> RegisterUserAsync(RegisterUserViewModel viewModel)
{
    // verify unique email

    //persist anonymous user 

    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(
        new ClaimsIdentity(
            new Claim[] {
            new Claim(ClaimTypes.Email, viewModel.EmailAddress),
            new Claim(ClaimTypes.GivenName, viewModel.LastName),
            new Claim(ClaimTypes.Name, viewModel.FirstName),
            new Claim(ClaimTypes.NameIdentifier, Guid.NewGuid().ToString() /* persisted value*/)

    }, CookieAuthenticationDefaults.AuthenticationScheme
    )));


    //return some id that react will now that user is logged in
    return Ok(new RegisterUserResponse() {  });
}

Question :

  1. on the RegisterUserResponse is safe to add an id and store it in the localstorage and this will indicate that the user is still logged in, to be used in guarded routes ? What is a secure approach to generate that identifier?
  2. I know that cookie is sent with each request and I can verify the claims to get the persisted anonymous user, can cookie value be altered, is a security risk?
  3. If the user chooses to create an account, do I need some identity provider for account managing, can be integrated with the react app. I saw a lot of examples using Razor Pages? like IdentityServer?
0

There are 0 best solutions below