Пример #1
0
    private async Task <(string ClientSecret, DateTimeOffset ExpiresAt)> GenerateNewSecretAsync(
        [NotNull] AppleGenerateClientSecretContext context)
    {
        var expiresAt = _clock.UtcNow.Add(context.Options.ClientSecretExpiresAfter).UtcDateTime;
        var subject   = new Claim("sub", context.Options.ClientId);

        Log.GeneratingNewClientSecret(_logger, subject.Value, expiresAt);

        var tokenDescriptor = new SecurityTokenDescriptor()
        {
            Audience = context.Options.TokenAudience,
            Expires  = expiresAt,
            Issuer   = context.Options.TeamId,
            Subject  = new ClaimsIdentity(new[] { subject }),
        };

        var    pem = await context.Options.PrivateKey !(context.Options.KeyId !, context.HttpContext.RequestAborted);
        string clientSecret;

        using (var algorithm = CreateAlgorithm(pem))
        {
            tokenDescriptor.SigningCredentials = CreateSigningCredentials(context.Options.KeyId !, algorithm);

            clientSecret = context.Options.SecurityTokenHandler.CreateToken(tokenDescriptor);
        }

        Log.GeneratedNewClientSecret(_logger, clientSecret);

        return(clientSecret, expiresAt);
    }
Пример #2
0
        private async Task <(string clientSecret, DateTimeOffset expiresAt)> GenerateNewSecretAsync(
            [NotNull] AppleGenerateClientSecretContext context)
        {
            var expiresAt = _clock.UtcNow.Add(context.Options.ClientSecretExpiresAfter).UtcDateTime;
            var subject   = new Claim("sub", context.Options.ClientId);

            _logger.LogDebug(
                "Generating new client secret for subject {Subject} that will expire at {ExpiresAt}.",
                subject.Value,
                expiresAt);

            var tokenDescriptor = new SecurityTokenDescriptor()
            {
                Audience = context.Options.TokenAudience,
                Expires  = expiresAt,
                Issuer   = context.Options.TeamId,
                Subject  = new ClaimsIdentity(new[] { subject }),
            };

            byte[] keyBlob = await _keyStore.LoadPrivateKeyAsync(context);

            string clientSecret;

            using (var algorithm = CreateAlgorithm(keyBlob))
            {
                tokenDescriptor.SigningCredentials = CreateSigningCredentials(context.Options.KeyId !, algorithm);

                clientSecret = _tokenHandler.CreateEncodedJwt(tokenDescriptor);
            }

            _logger.LogTrace("Generated new client secret with value {ClientSecret}.", clientSecret);

            return(clientSecret, expiresAt);
        }
    /// <inheritdoc />
    protected override async Task <OAuthTokenResponse> ExchangeCodeAsync([NotNull] OAuthCodeExchangeContext context)
    {
        if (Options.GenerateClientSecret)
        {
            var secretGenerationContext = new AppleGenerateClientSecretContext(Context, Scheme, Options);
            await Events.GenerateClientSecret(secretGenerationContext);
        }

        return(await base.ExchangeCodeAsync(context));
    }
Пример #4
0
        /// <inheritdoc />
        public override async Task <byte[]> LoadPrivateKeyAsync([NotNull] AppleGenerateClientSecretContext context)
        {
            if (context.Options.PrivateKeyBytes == null)
            {
                throw new ArgumentException(
                          $"The {nameof(AppleAuthenticationOptions.PrivateKeyBytes)} option must be set to be able to load the Sign in with Apple private key.",
                          nameof(AppleAuthenticationOptions.PrivateKeyBytes));
            }

            return(await context.Options.PrivateKeyBytes(context.Options.KeyId));
        }
Пример #5
0
        /// <inheritdoc />
        public override async Task <string> GenerateAsync([NotNull] AppleGenerateClientSecretContext context)
        {
            if (_clientSecret == null || _clock.UtcNow >= _expiresAt)
            {
                try
                {
                    (_clientSecret, _expiresAt) = await GenerateNewSecretAsync(context);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, $"Failed to generate new client secret for the {context.Scheme.Name} authentication scheme.");
                    throw;
                }
            }

            return(_clientSecret);
        }
Пример #6
0
    /// <inheritdoc />
    public override async Task <string> GenerateAsync([NotNull] AppleGenerateClientSecretContext context)
    {
        string key = CreateCacheKey(context.Options);

        return(await _cache.GetOrCreateAsync(key, async (entry) =>
        {
            try
            {
                (string clientSecret, DateTimeOffset expiresAt) = await GenerateNewSecretAsync(context);
                entry.AbsoluteExpiration = expiresAt;
                return clientSecret;
            }
            catch (Exception ex)
            {
                Log.ClientSecretGenerationFailed(_logger, ex, context.Scheme.Name);
                throw;
            }
        }));
    }
        /// <inheritdoc />
        public override async Task <string> GenerateAsync([NotNull] AppleGenerateClientSecretContext context)
        {
            string key = CreateCacheKey(context.Options);

            return(await _cache.GetOrCreateAsync(key, async (entry) =>
            {
                try
                {
                    (string clientSecret, DateTimeOffset expiresAt) = await GenerateNewSecretAsync(context);
                    entry.AbsoluteExpiration = expiresAt;
                    return clientSecret;
                }
                catch (Exception ex)
                {
                    _logger.LogError(
                        ex,
                        "Failed to generate new client secret for the {SchemeName} authentication scheme.",
                        context.Scheme.Name);

                    throw;
                }
            }));
        }
Пример #8
0
 /// <summary>
 /// Invoked whenever the client secret needs to be generated.
 /// </summary>
 /// <param name="context">Contains information about the current request.</param>
 /// <returns>
 /// A <see cref="Task"/> representing the completed operation.
 /// </returns>
 public virtual async Task GenerateClientSecret([NotNull] AppleGenerateClientSecretContext context) =>
 await OnGenerateClientSecret(context);
Пример #9
0
 /// <summary>
 /// Generates a client secret for Sign in with Apple as an asynchronous operation.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <returns>
 /// A <see cref="Task{TResult}"/> representing the asynchronous operation
 /// to generate a client secret for Sign in with Apple.
 /// </returns>
 public abstract Task <string> GenerateAsync(AppleGenerateClientSecretContext context);