-1

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

2 Answers 2

2
+50

i got it working with setting the DefaultScheme:

services.AddAuthentication(o =>
{
    o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    o.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    o.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, that worked! Only that i got an 404 instead of a 401 return code.
the cookieoptions has an LoginPath property which is "/Account/Login" by default - if this path does not exist, you get an 404 instead of 401 because of the redirect to the non existing page
I thought i overrwrite this by: options.Events.OnRedirectToLogin... But htis isn't called.
try options.Cookies.ApplicationCookie.AutomaticChallenge = false in AddIdentity method or set location header in OnRedirectToLogin :-)
0

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

Comments

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.