ClientProxy

From Logic Wiki
Jump to: navigation, search


ClientProxy.png

  public async Task<T> Get<T>(string uri, string urlSetting = "DefaultApi")
        {
            _logger.LogInformation($"Called ClientProxy.Get<T>(\"{uri}\", \"{urlSetting}\"");
            await  SetGlobals(urlSetting);
            var token = await GetToken(urlSetting);
            if (token == null)
            {
                throw new Exception("No token retrieved");
            }
                _logger.LogInformation($"Token: {token}, BaseUrl: {_baseURL}, ApiID: {_apiId}, SystemToken: {_identityServerToken}");
                var clientHandler = new HttpClientHandler();
                if (CookieContainer != null)
                {
                    clientHandler.UseCookies = true;
                    clientHandler.CookieContainer = CookieContainer;
                }
                using (HttpClient httpClient = new HttpClient(clientHandler))
                {
                    ConfigureClient(httpClient, token);
                    _logger.LogInformation($"Making API call");
                    var response = await httpClient.GetAsync(uri);
                    _logger.LogInformation($"Result: {response.StatusCode}, {response.ToString()}");
                    response.EnsureSuccessStatusCode();
                    return await Task.Run(() => GetResultFromResponse<T>(response));
                }
        }

       private async Task<bool> SetGlobals(string urlSetting)
        {
            _baseURL = _configuration.GetSection("ApiAuth").GetSection(urlSetting)["Url"];
            _apiId = _configuration.GetSection("ApiAuth").GetSection(urlSetting)["scope"];
            return true;
        }

 private async Task<string> GetToken(string apiName)
        {
            var tokens = _context.HttpContext.Session.GetString("Tokens");
            var sessionTokens = new List<Tokens>();
            if (tokens != null)
            {
                sessionTokens = JsonConvert.DeserializeObject<List<Tokens>>(tokens);
            }
        
            var targetToken = sessionTokens.Find(k => apiName == k.ApiName);
            if (targetToken != null && targetToken.ValidUntil < DateTime.Now)
            {
                return targetToken.TokenValue;
            }
            else
            {
                var apiInfo = GetApiInfoFromAppSettings(apiName);
                if (apiInfo != null)
                {
                    var token = await GetTokenFromIdServer(apiInfo.Scope, apiInfo.Name, apiInfo.Secret);
                    if (token != null)
                    {
                        sessionTokens = sessionTokens.Where(k => apiName.Contains(k.Uri)).ToList();
                        var accessToken = JsonConvert.DeserializeObject<Dictionary<string, string>>(token);
                        var apiEndPoint = new Tokens
                        {
                            ApiName = apiName,
                            Uri = apiInfo.UrL,
                            TokenName = apiInfo.Name,
                            TokenValue = accessToken["access_token"],
                            ValidUntil = DateTime.Now.AddMinutes(55)
                        };

                        sessionTokens.Add(apiEndPoint);
                        _context.HttpContext.Session.SetString("Tokens", JsonConvert.SerializeObject(sessionTokens));

                        return apiEndPoint.TokenValue;
                    }
                }
                return null;
            }
        }

        private ApiInfo GetApiInfoFromAppSettings(string apiName)
        {
            var retVal = new ApiInfo();
            var apiAuth = _configuration.GetSection("ApiAuth").GetSection(apiName);
                retVal.ApiName = apiName;
                retVal.UrL = apiAuth["Url"];
                retVal.Name = apiAuth["Name"];
                retVal.Scope = apiAuth["Scope"];
                retVal.Secret = apiAuth["Secret"];

            return retVal;
        }

        private async Task<string> GetTokenFromIdServer(string scope, string username, string secret)
        {
            using (var client = new HttpClient())
            {
                var loginApi = _configuration.GetSection("ApiAuth").GetSection("Auth");
                client.BaseAddress = new Uri(loginApi["Url"] + "/connect/token");
                var content = new FormUrlEncodedContent(new[]
                {
                    new KeyValuePair<string, string>("scope", scope),
                    new KeyValuePair<string, string>("grant_type", "client_credentials")
                });
                var byteArray = Encoding.ASCII.GetBytes($"{username}:{secret}");
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
                var result = await client.PostAsync("/connect/token", content);
                if (result.StatusCode != HttpStatusCode.OK) return null;
                var resultContent = await result.Content.ReadAsStringAsync();
                return resultContent;
            }
        }

   private void ConfigureClient(HttpClient httpClient, string token)
        {
            httpClient.SetBearerToken(token);
            httpClient.BaseAddress = new Uri(_baseURL);
            httpClient.DefaultRequestHeaders.Accept.Clear();
            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
            httpClient.DefaultRequestHeaders.Add("AppId", _configuration.GetSection("AppSettings")["AppId"]);
            httpClient.DefaultRequestHeaders.Add("CMSApplicationId", _configuration.GetSection("AppSettings")["CMSApplicationId"]);
            httpClient.DefaultRequestHeaders.Add("UserToken", token);
            if (!string.IsNullOrEmpty(ApplicationId))
            {
                httpClient.DefaultRequestHeaders.Add("ApplicationId", ApplicationId);
            }

            AddShowNonPublishedHeader(httpClient);
        }


        private class Tokens
        {
            public string ApiName { get; set; }
            public string TokenName { get; set; }
            public string Uri { get; set; }
            public string TokenValue { get; set; }
            public DateTime ValidUntil { get; set; }

        }

        private class ApiInfo
        {
            public string ApiName { get; set; }
            public string Name { get; set; }
            public string UrL { get; set; }
            public string Secret { get; set; }
            public string Scope { get; set; }

        }