Exemplo n.º 1
0
        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()));
        }
Exemplo n.º 2
0
        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)));
        }