Created
July 24, 2013 17:45
-
-
Save pcibraro/6072778 to your computer and use it in GitHub Desktop.
Katana Authentication Handler for Hawk
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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