1

I'm looking for a minimal example for a custom authentication writen in C# for asp.net core 2 based on for example API keys.

Mircosoft has a pretty good documentation about doing this with cookies, however this is not what I want. Since I want to use API keys (given by http-header, GET or Cookie, ...) I never make a call to HttpContext.SignInAsync and this is maybe the issue I can't find/google my way around.

I built an simple AuthenticationHandler (based on this - since I read that custom middlewares are not the way to go anymore) which looks something like this:

internal class CustomAuthHandler : AuthenticationHandler<CustomAuthOptions>
{
    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        // parse cookies to find APIKEY
        if(Context.Request.Cookies.ContainsKey("APIKEY"))
        {
            string APIKEY = Request.Cookies["APIKEY"];
            // ... checking DB for APIKEY ...

            // creating claims
            var claims = new[]
            {
                new Claim( /* ... */ ),
                // ...
            };

            var claimsIdentity = new ClaimsIdentity(claims);
            var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
            var ticket = new AuthenticationTicket(claimsPrincipal, new AuthenticationProperties(), "Custom Scheme");
            return AuthenticateResult.Success(ticket); // this line gets called
        }

        return AuthenticateResult.NoResult();
    }
}

But when I have an API endpoint with just the [Authorize] attribute the DenyAnonymousAuthorizationRequirement denies the request cause the user is not allowed (cause IsAuthenticated == false which is readonly, all claims are shown properly)

5
  • Some pointers, the AuthenticationScheme drives everything, and there is an overload for SignInAsync that accepts the auth scheme - so basically if you want to roll out your own auth then look at the AuthenticationMiddleware and scourer the Security repo Commented Jul 27, 2018 at 17:10
  • But when to call SignInAsync? I tried to call it in the auth handler but this has not changed the IsAuthenticated property Commented Jul 27, 2018 at 17:12
  • So I've created middleware above UseMvc or anything else that listens to /signin then when that endpoint gets called I will authenticate the user via what ever means, username/password or something then call signinasync Commented Jul 27, 2018 at 17:13
  • I don't use a classic login. When I try to implement SignInAsync from IAuthenticationSignInHandler` I don't find a way to set IsAuthenticated Commented Jul 27, 2018 at 19:45
  • IsAuthenticated is set when you set a principle on the context Commented Jul 27, 2018 at 19:46

1 Answer 1

5

Change var claimsIdentity = new ClaimsIdentity(claims); into something like var claimsIdentity = new ClaimsIdentity(claims, "Password"); (of course, instead of "Password" use the AuthenticationType that best fits your case).

Similar question here: Why is my ClaimsIdentity IsAuthenticated always false (for web api Authorize filter)?

Sign up to request clarification or add additional context in comments.

2 Comments

Wow, this fixed my auth handler too. That's really quite obscure.
I agree, perhaps the docs could be more clear on the usage.. I guess the idea is that claims can come from different sources, and you can either trust them all together or just trust particular claims from a specific source (in this case "Password" source), if you have more sources (e.g. external authentications like Auth0. Google, FB). That's probably why things didn't work until you specified the "Password" source.

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.