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); }
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 }); }