7

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.

9
  • What about chaining multiple middlewares? Commented May 16, 2018 at 12:47
  • How does one do that? Could you link to a basic example? :) Commented May 16, 2018 at 12:53
  • Who is your SSO Identity Provider? Commented May 16, 2018 at 13:37
  • I guess I misunderstood the problem at first. Now I think I know what the problem is. Why you are doing this process in HandleChallenge, and not in HandleAuthentication? Commented May 16, 2018 at 13:38
  • That is my question precisely :) Commented May 16, 2018 at 13:43

1 Answer 1

6

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.

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

1 Comment

Check this link as well, was quite useful. github.com/aspnet/AspNetCore/issues/4648#issuecomment-410330370

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.