简体   繁体   English

无法使用HttpClient获取API资源

[英]Can't get API resource using HttpClient

I'm using Identity Server4 and I have configured a web API project using ResourceOwnerPassword grant type. 我正在使用Identity Server4,并且已经使用ResourceOwnerPassword授予类型配置了Web API项目。

Web API method: Web API方法:

[HttpGet]
[Authorize(Roles = "Badmin")]
[Route("GetUsers")]
public IActionResult GetUsers()
{
    List<ApplicationUser> users = _context.ApplicationUsers
        .AsNoTracking().ToListAsync().Result;

    return Json(users);
}

In my console program code: 在我的控制台程序代码中:

if (response != null)
{
    using (HttpClient client = new HttpClient())
    {
        Console.WriteLine("AccessToken:" + Environment.NewLine + response.AccessToken);
        Console.WriteLine(Environment.NewLine);

        HttpResponseMessage resourceOwnerPasswordResponse = await client.GetAsync("https://localhost:44366/identity/GetUsers");

        client.DefaultRequestHeaders.Add("Bearer", response.AccessToken);

        if (!resourceOwnerPasswordResponse.IsSuccessStatusCode)
        {
            Console.WriteLine(resourceOwnerPasswordResponse.StatusCode);
            Console.WriteLine("HttpClient ResourceOwnerPassword Result: " + resourceOwnerPasswordResponse.StatusCode);
            Console.WriteLine(Environment.NewLine);
        }
        else
        {
            string result = await resourceOwnerPasswordResponse.Content.ReadAsStringAsync();
            Console.WriteLine("HttpClient ResourceOwnerPassword Result: " + Environment.NewLine + JsonConvert.DeserializeObject(result));
            Console.WriteLine(Environment.NewLine);
        }
    }
}

The second way: 第二种方式:

if (response != null)
{
    HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create("https://localhost:44366/identity/GetUsers");
    httpWebRequest.ContentType = "application/json";
    httpWebRequest.Headers.Add("Authorization", string.Format("Bearer {0}", response.AccessToken));
    httpWebRequest.Method = "GET";

    HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();

    string result = string.Empty;

    using (Stream responseStream = httpWebResponse.GetResponseStream())
    {
        if (responseStream != null)
        {
            StreamReader streamReader = new StreamReader(responseStream);
            result = streamReader.ReadToEnd();
            streamReader.Close();
        }
    }

    Console.WriteLine("HttpWebRequest ResourceOwnerPassword Result: " + Environment.NewLine + JsonConvert.DeserializeObject(result));
}

see the console result: 查看控制台结果:
查看控制台结果

So my questions is why when I use HttpCliet , I get the Unauthorized (code 401), while the second way got the user data successfully. 所以我的问题是为什么当我使用HttpCliet ,我得到了未经授权(代码401),而第二种方法成功地获得了用户数据。

Token should be added to the client before making the request and you need to make sure it is the Authorization header. 发出请求之前 ,应将令牌添加到客户端并且需要确保它是“ 授权”标头。

client.DefaultRequestHeaders.Authorization = 
    new AuthenticationHeaderValue("Bearer", response.AccessToken);

//OR

//client.DefaultRequestHeaders
//  .Add("Authorization", string.Format("Bearer {0}", response.AccessToken));

var resourceOwnerPasswordResponse = await client.GetAsync("https://localhost:44366/identity/GetUsers");

Which is why it worked in the second example and not the first 这就是为什么它在第二个示例而不是第一个示例中起作用的原因

The Web API action should also be async if using ToListAsync 如果使用ToListAsync则Web API操作也应该是异步的

[HttpGet]
[Authorize(Roles = "Badmin")]
[Route("GetUsers")]
public async Task<IActionResult> GetUsers() {
    var users = await _context.ApplicationUsers.AsNoTracking().ToListAsync();

    return Json(users);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM