如何使用 AuthorizedAttribute 向 API 控制器发出 HTTP 请求?

How to make HTTP requests to an API controller with AuthorizedAttribute?

短篇小说

我有一个 Web API。我想防止未经授权的请求,所以我将 [Authorize(Roles = "admin")] 属性添加到我的 ApiController.

如何从 C# 中的不同应用程序(例如从桌面应用程序)向我自己的 API 发出请求?

长话短说

我有一个简单的 Web 应用程序解决方案,其中包含 2 个项目。

project1 中,用户可以通过用户名和密码登录并执行操作。签署用户的代码如下所示:

if (ModelState.IsValid)
{
    var user = await _userManager.GetFromModelAsync(model); // just get user from DB
    var claims = new List<Claim>
    {
        new Claim(ClaimsIdentity.DefaultNameClaimType, user.Code),
        new Claim(ClaimsIdentity.DefaultRoleClaimType, user.Role?.Name)
    };
        
    var id = new ClaimsIdentity(
        claims, "ApplicationCookie",
        ClaimsIdentity.DefaultNameClaimType,
        ClaimsIdentity.DefaultRoleClaimType);

    await _httpContextAccessor.HttpContext.SignInAsync(
        CookieAuthenticationDefaults.AuthenticationScheme,
        new ClaimsPrincipal(id)); // I use httpContextAccessor cause I have this code not in controller
}

通过此身份验证,用户可以轻松访问具有属性 [Authorize(Roles = "user")] 的任何控制器。

Project2 中,我有 Admin Web API,它可以更改用户所做的事情。我想从桌面 C# 应用程序调用此 API 并且我还希望 API 具有授权要求(在我的情况下为 [Authorize(Roles = "admin")])。

例如,它看起来像这样:

[Authorize(Roles = "user")]
public class AdminApiController : Controller
{
    public async Task<IActionResult> Index()
    {
        return Ok("Ok");
    }
}

问题是:有了这样的身份验证机制,我应该如何向 API 和 HttpClient 发出 HTTP 请求?我知道的唯一方法是使用 WebClient 并使用 UploadValues 模拟授权到特殊授权表。

P.S。我尝试设置 HTTP Authorization header 但它不起作用。也许重点是为用户和管理员使用单独的身份验证机制?

非常感谢对此的任何帮助。

我认为您可以遵循身份验证机制 JWT(JSON web Token) 而不是 cookie,因为桌面应用程序是不使用网络浏览器的不同环境

用户认证场景

  1. 桌面应用程序通过用户名和密码参数登录到 Web API
  2. 如果通过,则为经过身份验证的用户生成一个令牌并作为响应返回它
  3. 当桌面应用命中 API 操作时,授权角色通过令牌修饰

要查看完整示例,请查看此 Url

这是桌面应用程序中的示例代码:

using Newtonsoft.Json;
...

var client = new HttpClient();

var httpRequestMessage = new HttpRequestMessage
    {
        Method = HttpMethod.Post,
        RequestUri = new Uri("https://api.domain.com/action"),
        Headers = { 
            { HttpRequestHeader.Authorization.ToString(), "Bearer xxxxxxxxxxxxxxxxxxx" },
            { HttpRequestHeader.Accept.ToString(), "application/json" },
            { "X-Version", "1" }
        },
        Content = new StringContent(JsonConvert.SerializeObject(svm))
    };

var response = client.SendAsync(httpRequestMessage).Result;