IAccessToken IOauthAuthenticatorSync <IJwtAuthenticationRequest, IAccessToken>
        .Authenticate(IJwtAuthenticationRequest authenticationRequest)
        {
            this.ThrowIfInvalid(authenticationRequest);

            return(this.withLocalValidation
                ? this.ValidateLocallySync(authenticationRequest)
                : this.ValidateRemoteSync(authenticationRequest));
        }
        async Task <IAccessToken> IOauthAuthenticator <IJwtAuthenticationRequest, IAccessToken>
        .AuthenticateAsync(IJwtAuthenticationRequest authenticationRequest, CancellationToken cancellationToken)
        {
            this.ThrowIfInvalid(authenticationRequest);

            return(this.withLocalValidation
                ? this.ValidateLocallySync(authenticationRequest)
                : await this.ValidateRemoteAsync(authenticationRequest, cancellationToken).ConfigureAwait(false));
        }
        private IAccessToken ValidateRemoteSync(IJwtAuthenticationRequest request)
        {
            var validationRequestHref = new StringBuilder()
                                        .Append(this.application.Href)
                                        .Append(OauthTokenPath)
                                        .Append(request.Jwt)
                                        .ToString();

            return(this.InternalSyncDataStore.GetResource <IAccessToken>(validationRequestHref));
        }
        private Task <IAccessToken> ValidateRemoteAsync(IJwtAuthenticationRequest request, CancellationToken cancellationToken)
        {
            var validationRequestHref = new StringBuilder()
                                        .Append(this.application.Href)
                                        .Append(OauthTokenPath)
                                        .Append(request.Jwt)
                                        .ToString();

            return(this.internalDataStore.GetResourceAsync <IAccessToken>(validationRequestHref));
        }
        private void ThrowIfInvalid(IJwtAuthenticationRequest request)
        {
            if (this.application == null)
            {
                throw new ApplicationException($"{nameof(this.application)} cannot be null.");
            }

            if (request == null)
            {
                throw new ApplicationException($"{nameof(request)} cannot be null.");
            }
        }
        private IAccessToken ValidateLocallySync(IJwtAuthenticationRequest request)
        {
            var options = this.localValidationOptions ?? new JwtLocalValidationOptions();

            // Allow the issuer claim to be manually specified. This is necessary
            // because ID Site tokens have a different issuer and break local validation
            // with the default rules.
            var expectedIssuer = options.Issuer;

            if (string.IsNullOrEmpty(expectedIssuer))
            {
                expectedIssuer = this.application.Href;
            }

            var parser = this.application.Client.NewJwtParser()

                         // Require secret key signature
                         .SetSigningKey(this.internalDataStore.ApiKey.GetSecret(), Encoding.UTF8)

                         // Require this application to be the issuer
                         .RequireIssuer(expectedIssuer);

            // During parsing, the JWT is validated for lifetime, signature, and tampering
            var jwt = parser.Parse(request.Jwt);

            // Build an IAccessToken instance from scratch
            var properties = new Dictionary <string, object>();

            var accessTokenHref            = this.application.Href.Replace(ApplicationPath, AccessTokenPath);
            var accessTokenIdStartingPoint = accessTokenHref.LastIndexOf("/") + 1;

            accessTokenHref = accessTokenHref.Substring(0, accessTokenIdStartingPoint);
            accessTokenHref = accessTokenHref + jwt.Body.Id;

            properties.Add(AbstractResource.HrefPropertyName, accessTokenHref);
            properties.Add(DefaultAccessToken.AccountPropertyName, new LinkProperty(jwt.Body.Subject));
            properties.Add(DefaultAccessToken.ApplicationPropertyName, new LinkProperty(this.application.Href));
            properties.Add(AbstractInstanceResource.CreatedAtPropertyName, DateTimeOffset.UtcNow);
            properties.Add(DefaultAccessToken.JwtPropertyName, request.Jwt);
            properties.Add(AbstractResource.TenantPropertyName, (this.application as DefaultApplication).Tenant);

            var accessToken = this.internalDataStore.InstantiateWithData <IAccessToken>(properties);

            return(accessToken);
        }
 /// <summary>
 /// Synchronously executes the OAuth 2.0 Authentication Request and returns the result.
 /// </summary>
 /// <param name="authenticator">The <see cref="IJwtAuthenticator"/>.</param>
 /// <param name="authenticationRequest">The Authentication Request this authenticator will attempt.</param>
 /// <returns>An Authentication Result representing the successful authentication.</returns>
 /// <exception cref="Error.ResourceException">The authentication failed.</exception>
 public static IAccessToken Authenticate(this IJwtAuthenticator authenticator, IJwtAuthenticationRequest authenticationRequest)
 => (authenticator as IJwtAuthenticatorSync).Authenticate(authenticationRequest);
 /// <summary>
 /// Synchronously executes the OAuth 2.0 Authentication Request and returns the result.
 /// </summary>
 /// <param name="authenticator">The <see cref="IJwtAuthenticator"/>.</param>
 /// <param name="authenticationRequest">The Authentication Request this authenticator will attempt.</param>
 /// <returns>An Authentication Result representing the successful authentication.</returns>
 /// <exception cref="Error.ResourceException">The authentication failed.</exception>
 public static IAccessToken Authenticate(this IJwtAuthenticator authenticator, IJwtAuthenticationRequest authenticationRequest)
     => (authenticator as IJwtAuthenticatorSync).Authenticate(authenticationRequest);