Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a programmatic login for web api

I am trying to login using the HttpContext.SignInAsync inside a controller in .net core 2.0 The following is the same controller I used in .net core 1.1 and it worked fine.

[Route("Login/{username}")]
public async Task<IActionResult> Login(string username)
{
        var userClaims = new List<Claim>
        {
            new Claim(ClaimTypes.Name, username),
            new Claim(ClaimTypes.Role, "custom")
        };

        var principal = new ClaimsPrincipal(new ClaimsIdentity(userClaims, "local"));
        await HttpContext.SignInAsync("DefaultAuthenticationScheme", principal);
        return Ok("done");
}

Then running the above code I see no output in the website. On debugging I don't see it crossing await line of code. I am assuming the function is getting completed before the SignInAsync function can run. But I didn't face that issue in core 1.1.

My changes to the startup.cs file are as follows:

services.AddAuthentication("DefaultAuthenticationScheme")
        .AddCookie();

And in the Configure:

app.UseAuthentication();

I am also trying to create a filter that can do the same kind of login. However since I would be overriding the filter functions, I cannot make it an async function and hence can't call await on this async function.

like image 513
Neville Nazerane Avatar asked Mar 03 '26 10:03

Neville Nazerane


2 Answers

You should add the Authorize attribute to the controller/methods you want have the redirect to Login if not authenticated/authorized.

UPDATE

I got it to work if you add this in your ConfigureServices method, replacing what you have:

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie(o => o.LoginPath = new PathString("/Login"));
like image 97
Mihail Stancescu Avatar answered Mar 06 '26 00:03

Mihail Stancescu


I misunderstood the concept as the AddAuthentication function takes in a string which would be a custom name for the configuration I set up. This name can later be used to reference the configuration in the SignInAsync function. Thanks to the pointers from @Mihali's answer, with some trial and errors I figured out how they actually work.

First of all the SignInAsync function takes in a string that refers to a scheme. For instance if I want the default scheme that stores cookies I could use "Cookies" like this:

await HttpContext.SignInAsync("Cookies", principal);

Alternatively, instead of "Cookies" we can always use the constant that stores the string CookieAuthenticationDefaults.AuthenticationScheme as provided by @Mihali.

The string parameter in the AddAuthentication function takes in is meant to be set as the default scheme. This default scheme can be used directly in functions such as SignInAsync (above) and SignOutAsync. So I can have my start up config set up with a default scheme like this:

services.AddAuthentication("Cookies")
        .AddCookie();

In this case I do not have to explicitly mention "Cookies" each time I use the sign in and sign out functions. I can simply use:

await HttpContext.SignInAsync(principal);

This would use the default scheme set up in the startup.cs.

like image 31
Neville Nazerane Avatar answered Mar 06 '26 00:03

Neville Nazerane



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!