.net 通过HttpClient C#在受保护的API中成功认证后自动传递承载令牌和X-Token

blpfk2vs  于 2023-05-19  发布在  .NET
关注(0)|答案(1)|浏览(166)

我正在使用.NET Core API应用程序使用外部API,在成功验证外部API后,我检索了授权头的承载令牌,然后是“X-Token”头:

request.Headers.Add("Authorization","Bearer "+token);
request.Headers.Add("X-Token", token);

我想在这个API中使用其他受保护的资源,我需要在调用这些资源时自动传递授权头中的承载令牌和“X-Token”,我实现了将这两个令牌存储在数据库中,直到我找到正确的方式来自动传递它们,因为有些教程我发现它们令人困惑。

在HttpClient请求头中自动传递这些令牌的最佳方法是什么?
问题编辑

我有一个API项目,它消耗了一个外部受保护的API资源:
我有两种方法:

public async Task<Xtoken> Authenticate()
        {
            Xtoken Xtoken= null;
            string bearer = "";
            var handler = new HttpClientHandler();
            HttpClient client = new HttpClient(handler);
            string basicToken = Narsa.ClientID + ":" + Narsa.ClientSecret;
            var basicBytes = System.Text.Encoding.UTF8.GetBytes(basicToken);
            string basic = Convert.ToBase64String(basicBytes);

            handler.ClientCertificateOptions = ClientCertificateOption.Manual;
            handler.ServerCertificateCustomValidationCallback =
                (httpRequestMessage, cert, cetChain, policyErrors) =>
                {
                    return true;
                };

            #region Get Authorization

            client.DefaultRequestHeaders.Add("Authorization", "Basic " + basic);
            var request = new HttpRequestMessage(HttpMethod.Post, Narsa.tokenUrl);
            request.Headers.Add("Authorization", "Basic " + basic);
            var collection = new List<KeyValuePair<string, string>>();
            collection.Add(new("grant_type", "client_credentials"));
            collection.Add(new("scope", "scope"));
            var content = new FormUrlEncodedContent(collection);
            request.Content = content;
            var response = await client.SendAsync(request);
            response.EnsureSuccessStatusCode();
      

            BearerToken bearertoken = null;
            string jsonResp = "";
            using (HttpContent httpcontent = response.Content)
            {
                jsonResp = httpcontent.ReadAsStringAsync().Result;
                if (response.StatusCode != System.Net.HttpStatusCode.OK)
                {
                    return null;
                }
              
           
                // Parsing the JSON response to get the token
                try
                {
                    tokenBearer= JsonConvert.DeserializeObject<BearerToken>(jsonResp);

BearerToken bearertoken = new BearerToken ()
            {
                access_token = tokenBearer.access_token,
                expires_in = tokenBearer.expires_in,
                scope = tokenBearer.scope,
                token_type = tokenBearer.token_type
            };
            _db.BearerToken.Add(bearertoken );
            await _db.SaveChangesAsync();
         

                }
                catch (Exception e5)
                {
                    e5.InnerException.ToString();
                }
//I want to keep the bearer access token to use it for getting the 2nd token.
                bearer= token.access_token ;

            }

            #endregion

            #region Authenticate 

            Guid GeneratedGUID = Guid.Empty;
            GeneratedGUID = Helpers.generateUUID(GeneratedGUID);
            string narsaGeneratedPassword = "NARSATEST" + DateTime.Now.ToString("yyyyMMdd") + Narsa.narsafinancingSecret;
            narsaGeneratedPassword = Helpers.GenerateNarsaPassword(narsaGeneratedPassword);

           

            HttpClient client1 = new HttpClient(handler);
          //  string basicToken1 = Narsa.ClientID + ":" + Narsa.ClientSecret;
           // var basicBytes1 = System.Text.Encoding.UTF8.GetBytes(basicToken);
           // string basic1 = Convert.ToBase64String(basicBytes);
          //  string tokenNarsa = "";
//Here I set the bearer token that I got from the first scope above in default authorization header. 
            client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", bearer);
            HttpRequestMessage request1 = new HttpRequestMessage(HttpMethod.Post, Narsa.AuthUri);
            request.Headers.Add("X-Client-ID", Narsa.ClientID);
            request.Headers.Add("X-Request-ID", GeneratedGUID.ToString());
            request.Headers.Add("X-Request-Application-Name", "ADD");

            var postData = new
            {
                UserName = Narsa.user,
                Password = narsaGeneratedPassword
            };

            var content1 = new StringContent(JsonConvert.SerializeObject(postData), Encoding.UTF8, "application/json");
            request1.Content = content1;
            var response1 = await client.SendAsync(request1);

            string jsonResp1 = "";
            using (HttpContent httpcontent1 = response1.Content)
            {
                jsonResp1 = httpcontent1.ReadAsStringAsync().Result;
              
                try
                {
                    Xtoken= JsonConvert.DeserializeObject<XToken>(jsonResp);
                }
                catch (Exception e5)
                {
                    e5.InnerException.ToString();
                }

            }
            JetonNarsa jeton = new JetonNarsa()
            {
                access_token = tokenBearer.access_token,
                expires_in = tokenBearer.expires_in,
                scope = tokenBearer.scope,
                token_type = tokenBearer.token_type
            };
            _db.JetonNarsa.Add(jeton);
            await _db.SaveChangesAsync();
         

            return Xtoken;
            #endregion

  

        }

正如你可能注意到的,我把这两个访问令牌作为TEST存储在我的DB中,以便在执行HttpClient请求时在其他方法中调用它们。E.g

public async Task<ResponseOptions> DeclareAPledge(DeclarNantissement_DTO obj)
        {
            Guid GeneratedGUID = Guid.Empty;
            GeneratedGUID = Helpers.generateUUID(GeneratedGUID);
            //I get these acess token them from my DB in order to call a protected action in that external API 
            var token = _db.JetonNarsa.Select(x => x.access_token).FirstOrDefault();
            var bearer = _db.BearerToken.Select(x => x.access_token).FirstOrDefault();
            
            var client = new HttpClient();
            var request = new HttpRequestMessage(HttpMethod.Post, Narsa.DeclarationNantiUri);
             client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", bearer);

            request.Headers.Add("X-Client-ID", Narsa.ClientID);
            request.Headers.Add("X-Request-ID", GeneratedGUID.ToString());
            request.Headers.Add("X-Request-Application-Name", "ADD");
            request.Headers.Add("X-Token", token);

            DeclarNantissement_DTO postData = new DeclarNantissement_DTO
            {
                idRequete = GeneratedGUID,
                codeSF = obj.codeSF,
                immatVeh1 = obj.immatVeh1,
                immatVeh2 = obj.immatVeh2,
                immatVeh3 = obj.immatVeh3,
                numChassis = obj.numChassis,
                dateNantissement = obj.dateNantissement,
                TypeVehicule = obj.TypeVehicule,
                numContrat = obj.numContrat,
                numWW = obj.numWW,
                idBeneficiare=obj.idBeneficiare,
                idType=obj.idType,
                intituleBeneficiaire=obj.intituleBeneficiaire,
                villeRC =obj.villeRC

            };
            var content = new StringContent(JsonConvert.SerializeObject(postData), null, "application/json");
            request.Content = content;
            var response = await client.SendAsync(request);
            response.EnsureSuccessStatusCode();
        

            string jsonResp = "";
            ResponseOptions Resp = null;
            using (HttpContent httpcontent = response.Content)
            {
                jsonResp = httpcontent.ReadAsStringAsync().Result;

                if (string.IsNullOrEmpty(jsonResp))
                {

                    return null;
                }

                try
                {
                    Resp = JsonConvert.DeserializeObject<ResponseOptions>(jsonResp);
                  
                }
                catch (Exception Ex)
                {
                }

            }
            return Resp;

        }

*如何存储这些令牌,以便将其用于外部API的受保护操作?

hmae6n7t

hmae6n7t1#

您将它们放在HttpClient的默认请求头中。例如:

var client = new HttpClient
{
    DefaultRequestHeaders = 
    {
        Authorization = new AuthenticationHeaderValue("Bearer", accessToken)
    },
};

您还可以添加自定义标题,如

client.DefaultRequestHeaders.Add("myHeader", "MyValue");

注意:因此,所有使用HttpClient示例的东西都会用到这些。

相关问题