Flo
Flo

Reputation: 1207

ASP.NET core API - cookie auth

I try to secure up my API with a cookie token.

Everything is working fine, i try to sign in i generate a cookie the cookie is set by browser, and then i try to request /auth/info2. The cookie is send but i got an 401 error.

Can u give me a hint? How to solve this problem?

Currently my code looks like that:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        {
            //options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))
            options.UseInMemoryDatabase("som_tmp");
        }
    );

    services.AddTransient<IEmailSender, EmailSender>();
    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

    services.AddIdentity<SomUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>();

    services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(o =>
        {
            o.Cookie = new CookieBuilder()
            {
                HttpOnly = false,
                Name = "som_session"
            };
        });

    services.ConfigureApplicationCookie(options =>
    {
        options.Events.OnRedirectToLogin = context =>
        {
            context.Response.StatusCode = 401;
            return Task.CompletedTask;
        };
    });

    services.AddAuthorization();

    services.AddMvc();
    services.AddOData();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ApplicationDbContext context, UserManager<SomUser> userManager, RoleManager<IdentityRole> roleManager)
{
    var model = GetEdmModel(app.ApplicationServices);

    app.UseDefaultFiles();

    app.UseStaticFiles(new StaticFileOptions
    {
        ServeUnknownFileTypes = true
    });

    app.UseAuthentication();

    app.UseMvc(routebuilder =>
    {
        routebuilder.Count().Filter().OrderBy().Expand().Select().MaxTop(null);
        routebuilder.MapODataServiceRoute("oData", "oData", model);
    });


    DbInitializer.Initialize(context, userManager, roleManager);
}

Controller:

[Authorize]
[HttpGet("info2")]
public async Task<JsonResult> Get2()
{
    return Json("Info2");
    //return Json( await GetCurrentUser() );
}

[AllowAnonymous]
[HttpPost("login2")]
public async Task<JsonResult> Login2([FromBody] LoginDto loginDto)
{
    var user = await _userManager.FindByNameAsync(loginDto.Username);
    if (user == null)
    {
        user = await _userManager.FindByEmailAsync(loginDto.Username);
    }

    if (user != null)
    {
        var passwordHasher = new PasswordHasher<SomUser>();
        if (passwordHasher.VerifyHashedPassword(user, user.PasswordHash, loginDto.Password) == PasswordVerificationResult.Success)
        {
            var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
            identity.AddClaim(new Claim(ClaimTypes.Name, user.UserName));
            await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity));
            return Json(true);
        }
    }

    return Json(false);
}

Upvotes: -1

Views: 987

Answers (2)

akhileshcoer
akhileshcoer

Reputation: 162

You will receive 401 atleast once since there a redirection to login involved. second result should have 'true' as a output.

Upvotes: 0

cyptus
cyptus

Reputation: 3396

i got it working with setting the DefaultScheme:

services.AddAuthentication(o =>
{
    o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    o.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    o.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})

Upvotes: 2

Related Questions