Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass custom data to HandleChallengeAsync

I have a Web API with a custom authenication scheme that reads auth tokens. Authentication can fail (401) for a number of reasons (token missing, invalid, expired), so I'd like to be able to indicate the failure reason in the HTTP response. E.g., 401 Token has expired.

Tokens are parsed and validated in AuthenticationHandler<T>.HandleAuthenticateAsync. How do I pass the failure reason from that method to HandleChallengeAsync?

protected override Task<AuthenticateResult> HandleAuthenticateAsync()
{
  AuthenticateResult result = null;
  var tokenResult = this.ParseToken(this.Request, out var token);

  if (tokenResult == TokenResult.Normal)
  {
    result = AuthenticateResult.Success(this.ticketFactory.CreateAuthenticationTicket(token));
  }
  else
  {
    result = AuthenticateResult.Fail("Bad token");
    // FIXME: Figure out how to populate the Properties property
    //result.Properties.Items.Add(nameof(TokenResult), tokenResult.ToString());
  }

  return Task.FromResult(result);
}

AuthenticationProperties.Items looks like a good place to store this type of custom data. But I can't figure out how to create an AuthenticationProperties object inside of HandleAuthenticateAsync and attach it to an AuthenticateResult object. Is there a way?

like image 819
lencharest Avatar asked Dec 04 '17 18:12

lencharest


1 Answers

The authentication handler is transient-scoped, as you can see here in the source code: https://github.com/dotnet/aspnetcore/blob/4dd2a883a4b22cf3df5944b1224355a94158f516/src/Security/Authentication/Core/src/AuthenticationBuilder.cs#L48

Every request will get their own instance of the handler, so you can set the failure reason as an instance field.

like image 157
juunas Avatar answered Nov 09 '22 23:11

juunas