public AuthenticationHeaderValue GenerateAuthenticationHeader( string endpointUri, string jsonContent = null) { var parameter = new HmacAuthenticationParameter { ApplicationKey = this.ApplicationSecrets.ApplicationKey, AuthenticatedUser = this.UserLookup.GetAuthenticatedUser(), Time = InstantPattern.General.Format(this.Clock.GetCurrentInstant()), }; parameter.Hash = HmacHashGenerator.Generate( parameter, this.ApplicationSecrets.ApplicationSecretKey, endpointUri, jsonContent); return(new AuthenticationHeaderValue("hmac", parameter.ToJson())); }
protected async override Task <AuthenticateResult> HandleAuthenticateAsync() { var authorizationHeader = this.Request.Headers["Authorization"]; var remoteIPAddress = this.Context.Connection.RemoteIpAddress; this.Logger?.LogDebug( "Request came from remote IP Address: {RemoteIPAddress}. Continuing with auth check.", remoteIPAddress.ToJson()); if (!authorizationHeader.Any()) { this.Logger?.LogWarning( "Failing authentication from IP {RemoteIPAddress} for application: {Reason}", remoteIPAddress.ToJson(), "No authorization header found"); return(AuthenticateResult.Fail("No authorization header found")); } if (!TryGetHmacAuthenticationParameter(this.Logger, remoteIPAddress, authorizationHeader[0] ?? string.Empty, out var parameter)) { this.Logger?.LogWarning("Failing authentication from IP {RemoteIPAddress}: {Reason}", remoteIPAddress.ToJson(), "Invalid HMAC authentication parameter"); return(AuthenticateResult.Fail("Invalid HMAC authentication parameter")); } if (!this.ApplicationSecretStore.TryGetValue(parameter.ApplicationKey, out var applicationSecret)) { this.Logger?.LogWarning("Failing authentication from IP {RemoteIPAddress}: {Reason}. Parameters: {Parameters}", remoteIPAddress.ToJson(), "No secret found for application key", parameter.ToJson()); return(AuthenticateResult.Fail("No secret found for application key")); } if (!IsRequestFresh(parameter, out var freshnessIndicator)) { this.Logger?.LogWarning( "Failing authentication from IP {RemoteIPAddress}: {Reason}. Parameters: {Parameters}. Freshness Indicator: {FreshnessIndicator}", remoteIPAddress.ToJson(), "HMAC authentication request is not fresh", parameter.ToJson(), freshnessIndicator.ToJson()); return(AuthenticateResult.Fail("HMAC authentication request is not fresh")); } var includeBodyInHash = this.Request.ContentLength.HasValue && this.Request.ContentLength.Value > 0; var requestBody = includeBodyInHash ? await ReadRequestBody(this.Request).ConfigureAwait(false) : string.Empty; var displayUrl = this.Request.GetDisplayUrl(); var hash = HmacHashGenerator.Generate( parameter, applicationSecret, displayUrl, requestBody); if (hash != parameter.Hash) { this.Logger?.LogWarning( "Failing authentication from IP {RemoteIPAddress}: {Reason}. DisplayUrl: {DisplayUrl}. Parameters: {Parameters}. Includes body: {IncludeBodyInHash}.", remoteIPAddress.ToJson(), "HMAC request hashes do not match", displayUrl, parameter.ToJson(), includeBodyInHash); return(AuthenticateResult.Fail("HMAC request hashes do not match")); } this.Logger?.LogDebug( "HMAC authentication from IP {RemoteIPAddress} looks good. Building claims principal for User: {User}, ApplicationKey: {Application}, Time: {Time}.", remoteIPAddress.ToJson(), parameter.AuthenticatedUser, parameter.ApplicationKey, parameter.Time); var properties = new AuthenticationProperties(); properties.Items[nameof(HmacAuthenticationParameter.ApplicationKey)] = parameter.ApplicationKey; properties.Items[nameof(HmacAuthenticationParameter.AuthenticatedUser)] = parameter.AuthenticatedUser; properties.Items[nameof(HmacAuthenticationParameter.Time)] = parameter.Time; ClaimsIdentity identity = new GenericIdentity(parameter.AuthenticatedUser, HmacSchemeName); if (this.ClaimsProvider == null) { this.Logger?.LogWarning("The claims provider is null. Proceeding without attaching claims to identity."); } else { this.Logger?.LogDebug("Attaching claims to identity."); this.ClaimsProvider.AddClaimsTo(identity, properties); if (identity.Claims.Any()) { this.Logger?.LogDebug("Claims were successfully attached."); } else { this.Logger?.LogWarning("No claims were attached by the claims provider."); } } var user = new ClaimsPrincipal(identity); this.Logger?.LogDebug("Returning success with claims principal."); return(AuthenticateResult.Success(new AuthenticationTicket(user, properties, HmacSchemeName))); }