Skip to content

Instantly share code, notes, and snippets.

@pcibraro
Created July 24, 2013 17:45
Show Gist options
  • Save pcibraro/6072778 to your computer and use it in GitHub Desktop.
Save pcibraro/6072778 to your computer and use it in GitHub Desktop.
Katana Authentication Handler for Hawk
public class HawkAuthenticationHandler : AuthenticationHandler<HawkAuthenticationOptions>
{
private readonly ILogger logger;
public HawkAuthenticationHandler(ILogger logger)
{
this.logger = logger;
}
protected override Task<AuthenticationTicket> AuthenticateCore()
{
if (Request.Method.Equals("get", StringComparison.InvariantCultureIgnoreCase) &&
!string.IsNullOrEmpty(Request.Uri.Query))
{
var query = HttpUtility.ParseQueryString(Request.Uri.Query);
if (query["bewit"] != null)
{
this.logger.WriteInformation(string.Format("Bewit found {0}",
query["bewit"]));
try
{
var principal = Hawk.AuthenticateBewit(query["bewit"],
Request.Host,
Request.Uri,
this.Options.Credentials);
var identity = (ClaimsIdentity)((ClaimsPrincipal)principal).Identity;
var ticket = new AuthenticationTicket(identity, (AuthenticationExtra)null);
return Task.FromResult(ticket);
}
catch (SecurityException ex)
{
this.logger.WriteWarning("Unauthorized call. " + ex.Message);
return null;
}
}
}
AuthenticationHeaderValue authorization = null;
if (Request.GetHeader("authorization") != null)
{
authorization = AuthenticationHeaderValue.Parse(Request.GetHeader("authorization"));
}
if (authorization != null &&
!string.Equals(authorization.Scheme, HawkAuthenticationOptions.Scheme))
{
this.logger.WriteInformation(string.Format("Authorization skipped. Schema found {0}",
authorization.Scheme));
return null;
}
if (authorization == null ||
string.IsNullOrWhiteSpace(authorization.Scheme))
{
this.logger.WriteInformation("Authorization header not found");
return null;
}
else
{
if (string.IsNullOrWhiteSpace(authorization.Parameter))
{
this.logger.WriteWarning("Invalid header format");
return null;
}
if (string.IsNullOrWhiteSpace(Request.Host))
{
this.logger.WriteWarning("Missing Host header");
return null;
}
try
{
var principal = Hawk.Authenticate(authorization.Parameter,
Request.Method,
Request.Host,
Request.Uri,
this.Options.Credentials);
var identity = (ClaimsIdentity)((ClaimsPrincipal)principal).Identity;
var ticket = new AuthenticationTicket(identity, (AuthenticationExtra)null);
return Task.FromResult(ticket);
}
catch (SecurityException ex)
{
this.logger.WriteError(ex.ToString());
return null;
}
}
}
protected override Task ApplyResponseChallenge()
{
if (Response.StatusCode != 401)
{
return Task.FromResult<object>(null);
}
var ts = Hawk.ConvertToUnixTimestamp(DateTime.Now).ToString();
var challenge = string.Format("ts=\"{0}\" ntp=\"{1}\"",
ts, "pool.ntp.org");
Response.AddHeader("WWW-Authenticate", HawkAuthenticationOptions.Scheme + " " + challenge);
return Task.FromResult<object>(null);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment