IAccountResult IIdSiteSyncCallbackHandler.GetAccountResult()
        {
            var signingKeyBytes = Encoding.UTF8.GetBytes(
                this.internalDataStore.ApiKey.GetSecret());

            IJwtParser parser = new DefaultJwtParser(this.internalDataStore.Serializer);
            var        jwt    = parser
                                .SetSigningKey(signingKeyBytes)
                                .Parse(this.jwtResponse);

            HandlerShared.ThrowIfRequiredParametersMissing(jwt.Body);

            string apiKeyFromJwt = null;

            if (HandlerShared.IsError(jwt.Body))
            {
                jwt.Header.TryGetValueAsString(JwtHeaderParameters.KeyId, out apiKeyFromJwt);
            }
            else
            {
                apiKeyFromJwt = (string)jwt.Body.GetClaim(DefaultJwtClaims.Audience);
            }

            HandlerShared.ThrowIfJwtSignatureInvalid(apiKeyFromJwt, this.internalDataStore.ApiKey, jwt);
            HandlerShared.ThrowIfJwtIsExpired(jwt.Body);

            HandlerShared.IfErrorThrowIdSiteException(jwt.Body);

            if (!this.nonceStore.IsAsynchronousSupported || this.syncNonceStore == null)
            {
                throw new ApplicationException("The current nonce store does not support synchronous operations.");
            }

            var responseNonce = (string)jwt.Body.GetClaim(IdSiteClaims.ResponseId);

            this.ThrowIfNonceIsAlreadyUsed(responseNonce);
            this.syncNonceStore.PutNonce(responseNonce);

            HandlerShared.ThrowIfSubjectIsMissing(jwt.Body);

            var accountResult = HandlerShared.CreateAccountResult(jwt.Body, this.internalDataStore);
            var resultStatus  = HandlerShared.GetResultStatus(jwt.Body);

            if (this.resultListener != null)
            {
                this.DispatchResponseStatus(resultStatus, accountResult);
            }

            return(accountResult);
        }
        public DefaultIdSiteSyncCallbackHandler(IInternalDataStore internalDataStore, IHttpRequest httpRequest)
        {
            if (internalDataStore == null)
            {
                throw new ArgumentNullException(nameof(internalDataStore));
            }

            if (httpRequest == null)
            {
                throw new ArgumentNullException(nameof(httpRequest));
            }

            this.internalDataStore = internalDataStore;
            this.jwtResponse       = HandlerShared.GetJwtResponse(httpRequest);

            this.nonceStore     = new DefaultNonceStore(internalDataStore.CacheResolver);
            this.syncNonceStore = this.nonceStore as ISynchronousNonceStore;
        }