ASP.NET Core using custom authenticationhandler with cookieauthentication

10,607

I think what you're after may be solved with some new pieces in ASP.NET Core 2.1

<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.1.0-rc1-final" />

Here's a sample of how to "select" auth schemes based on httpcontext data:

builder.AddPolicyScheme("scheme", "scheme", opts =>
{
    opts.ForwardDefaultSelector = ctx =>
    {
        if (ctx.Request.Query.ContainsKey("isRedirectedFromSSO"))
        {               
            return null; // or ctx.ForbidAsync(), not sure here.
        }

        return OpenIdConnectDefaults.AuthenticationScheme; // or your own sso scheme, whatever it may be here.
    };
})
.AddCookie()
.AddOpenIdConnect();

Have a look in this GitHub thread.

Share:
10,607
severin
Author by

severin

Updated on June 14, 2022

Comments

  • severin
    severin almost 2 years

    I'm trying to create my own AuthenticationHandler and use with cookie authentication:

    services.AddAuthentication(options =>
      {
      options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
      options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
      options.DefaultChallengeScheme = MyAuth.Scheme;
      })
      .AddCookie()
      .AddScheme<MyAuthenticationOptions, MyAuthenticationHandler>(MyAuth.Scheme, "My auth scheme", options => { });
    

    .

    public MyAuthenticationHandler(...) : base(...) {}
    
        protected override Task<AuthenticateResult> HandleAuthenticateAsync()
        {
            throw new NotImplementedException();  
        }    
    
        protected override async Task HandleChallengeAsync(AuthenticationProperties properties)
        {                     
            var myUser = await DoAuth();
    
            if (!myUser.IsAuthenticated)
            {
                if (Context.Request.Query.ContainsKey("isRedirectedFromSSO"))
                {
                    Context.Response.Redirect("/unauthorized");
                    return;
                }
                else
                {
                    Context.Response.Redirect("url to sso");
                    return;
                }              
            }    
    
            var claims = new List<Claim>
            {
                new Claim(ClaimTypes.NameIdentifier, user.Username),            
            };
    
            var identity = new ClaimsIdentity(claims, MyAuth.Scheme);
            var claimsPrincipal = new ClaimsPrincipal(identity);
    
            var authProperties = new AuthenticationProperties {};
    
            await Context.SignInAsync(
                CookieAuthenticationDefaults.AuthenticationScheme,
                claimsPrincipal,
                authProperties);
    
            Context.Response.Redirect(Request.GetEncodedUrl());
        }
    }
    
    1. If there is a valid auth cookie, auth using that
    2. If there is not a valid auth cookie, challenge using my auth and create an auth cookie if successful

    This works in practice, but I find it a little weird I'm doing the actual authentication in HandleChallenge and redirecting if it fails. It also seems odd to me to be calling one AuthenticationHandler (cookie) from another (MyAuthenticationHandler).

    How can I set this up correctly so that I'm doing the implementation in HandleAuthenticate instead? With my current implementation that method is never actually called.

    Also, is it ok to call one authentication handler from another?

    P.S. I have looked at several other posts and articles (including this, this and this), but I have not been able to find the answers to my questions from looking at them. Any help would be appreciated.

  • Suketu Bhuta
    Suketu Bhuta almost 5 years