public void AddGraphTypeFields(QueryCore queryCore)
        {
            queryCore.FieldAsync <ListGraphType <TokenExchangeResponseType> >(name: "tokenExchange",
                                                                              description: $"Given a proper list of OAuth2 Tokens, returns an authorization payload for downstream authorized calls.",
                                                                              arguments: new QueryArguments(new QueryArgument <NonNullGraphType <TokenExchangeInput> > {
                Name = "input"
            }),
                                                                              resolve: async context =>
            {
                try
                {
                    var graphQLUserContext = context.UserContext as GraphQLUserContext;


                    _summaryLogger.Add("query", "bind");
                    var input = context.GetArgument <BindInputModel>("input");

                    if (input.Tokens == null || input.Tokens.Count == 0)
                    {
                        throw new Exception("no tokens present in the request!");
                    }
                    var requestedFields = (from item in context.SubFields
                                           select item.Key).ToList();

                    var summaryLog = string.Join(";", _summaryLogger.Select(x => x.Key + "=" + x.Value).ToArray());


                    _summaryLogger.Add("requestedFields", string.Join(" ", requestedFields));

                    var tokens = (from item in input.Tokens
                                  let c = new TokenWithScheme()
                    {
                        Token = item.Token,
                        TokenScheme = item.TokenScheme
                    }
                                  select c).ToList();

                    var tokenExchangeRequest = new TokenExchangeRequest()
                    {
                        Tokens = tokens,
                        Extras = input.Extras
                    };
                    var tokenExchangeResponse = await _tokenExchangeHandlerRouter.ProcessExchangeAsync(input.Exchange, tokenExchangeRequest);

                    return(tokenExchangeResponse);
                }
                catch (Exception e)
                {
                    _summaryLogger.Add("exception", e.Message);
                    context.Errors.Add(new ExecutionError("Unable to process request", e));
                }

                return(null);
            },
                                                                              deprecationReason: null);
        }
        async Task <string> GetTokenAsync()
        {
            var           httpClient    = _defaultHttpClientFactory.HttpClient;
            TokenResponse tokenResponse = null;

            if (!_memoryCache.TryGetValue(_cacheKey, out tokenResponse))
            {
                // Key not in cache, so get data.
                var discoveryResponse = await DiscoveryCache.GetAsync();

                tokenResponse = await httpClient.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
                {
                    Address      = discoveryResponse.TokenEndpoint,
                    ClientId     = _settings.ClientId,
                    ClientSecret = _settings.ClientSecret
                });

                // Set cache options.
                var cacheEntryOptions = new MemoryCacheEntryOptions()
                                        // Keep in cache for this time, reset time if accessed.
                                        .SetSlidingExpiration(TimeSpan.FromMinutes(3));

                // Save data in cache.
                _memoryCache.Set(_cacheKey, tokenResponse, cacheEntryOptions);
                if (tokenResponse.IsError)
                {
                    _summaryLogger.Add("client_credentials_error", $"clientId:{_settings.ClientId} error:{tokenResponse.Error} endpoint:{discoveryResponse.TokenEndpoint}");
                }
            }
            return(tokenResponse.AccessToken);
        }
Beispiel #3
0
        public async Task <List <TokenExchangeResponse> > ProcessExchangeAsync(TokenExchangeRequest tokenExchangeRequest)
        {
            if (await _pipelineTokenExchangeHandlerRouter.PipelineTokenExchangeHandlerExistsAsync(_pipelineExchangeRecord
                                                                                                  .FinalExchange))
            {
                Dictionary <string, List <KeyValuePair <string, string> > > mapOpaqueKeyValuePairs =
                    new Dictionary <string, List <KeyValuePair <string, string> > >();
                if (_pipelineExchangeRecord.Preprocessors != null)
                {
                    foreach (var preProcessor in _pipelineExchangeRecord.Preprocessors)
                    {
                        var preProcessorHandler = _tokenExchangeHandlerPreProcessorStore.Get(preProcessor);
                        if (preProcessor == null)
                        {
                            var message = $"The preprocessor:{preProcessor} does not exist!";
                            _logger.LogCritical(message);
                            throw new Exception(message);
                        }

                        _logger.LogInformation($"The preprocessor:{preProcessor} was found!");
                        var opaqueKeyValuePairs = await preProcessorHandler.ProcessAsync(ref tokenExchangeRequest);

                        if (opaqueKeyValuePairs.Any())
                        {
                            mapOpaqueKeyValuePairs.Add(preProcessor, opaqueKeyValuePairs);
                        }
                    }
                }

                _logger.LogInformation($"Forwarding request to finalExchange:{_pipelineExchangeRecord.FinalExchange}!");
                var result = await _pipelineTokenExchangeHandlerRouter.ProcessFinalPipelineExchangeAsync(
                    _pipelineExchangeRecord.FinalExchange,
                    tokenExchangeRequest,
                    mapOpaqueKeyValuePairs);

                _summaryLogger.Add($"pipelineExchange_{_pipelineExchangeRecord.ExchangeName}", "OK");
                return(result);
            }
            else
            {
                var message = $"The finalExchange:{_pipelineExchangeRecord.FinalExchange} does not exist!";
                _logger.LogCritical(message);
                _summaryLogger.Add($"pipelineExchange_{_pipelineExchangeRecord.ExchangeName}", "FATAL");
                throw new Exception(message);
            }
        }
        public async Task <List <TokenExchangeResponse> > ProcessExchangeAsync(TokenExchangeRequest tokenExchangeRequest)
        {
            if (tokenExchangeRequest.Extras == null || tokenExchangeRequest.Extras.Count == 0)
            {
                throw new Exception($"{Name}: We require that extras be populated!");
            }

            List <ValidatedToken> validatedIdentityTokens = new List <ValidatedToken>();

            foreach (var item in tokenExchangeRequest.Tokens)
            {
                var prince = await _tokenValidator.ValidateTokenAsync(new TokenDescriptor
                {
                    TokenScheme = item.TokenScheme,
                    Token       = item.Token
                });

                var sub = prince.GetSubjectFromPincipal();
                if (string.IsNullOrEmpty(sub))
                {
                    _summaryLogger.Add("subject", "A subject was not found in the ClaimsPrincipal object!");
                    throw new Exception("A subject was not found in the ClaimsPrincipal object!");
                }
                validatedIdentityTokens.Add(new ValidatedToken
                {
                    Token       = item.Token,
                    TokenScheme = item.TokenScheme,
                    Principal   = prince
                });
            }

            // for this demo, lets assume all the extras are roles.
            var roles = tokenExchangeRequest.Extras;

            roles.Add("user");


            ResourceOwnerTokenRequest resourceOwnerTokenRequest = new ResourceOwnerTokenRequest()
            {
                AccessTokenLifetime = 3600,
                ArbitraryClaims     = new Dictionary <string, List <string> >()
                {
                    { "role", roles }
                },
                Scope    = "offline_access graphQLPlay",
                Subject  = validatedIdentityTokens[0].Principal.GetSubjectFromPincipal(),
                ClientId = "arbitrary-resource-owner-client"
            };
            var response = await _tokenMintingService.MintResourceOwnerTokenAsync(resourceOwnerTokenRequest);

            if (response.IsError)
            {
                throw new Exception(response.Error);
            }

            var tokenExchangeResponse = new TokenExchangeResponse()
            {
                accessToken = new AccessTokenResponse()
                {
                    access_token  = response.AccessToken,
                    refresh_token = response.RefreshToken,
                    expires_in    = response.ExpiresIn,
                    token_type    = response.TokenType,
                    authority     =
                        $"{_httpContextAssessor.HttpContext.Request.Scheme}://{_httpContextAssessor.HttpContext.Request.Host}",
                    HttpHeaders = new List <HttpHeader>
                    {
                        new HttpHeader()
                        {
                            Name = "x-authScheme", Value = response.Scheme
                        }
                    }
                }
            };

            return(new List <TokenExchangeResponse> {
                tokenExchangeResponse
            });
        }