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());
}
}
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With