如何使用 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,因为桌面应用程序是不使用网络浏览器的不同环境
用户认证场景
- 桌面应用程序通过用户名和密码参数登录到 Web API
- 如果通过,则为经过身份验证的用户生成一个令牌并作为响应返回它
- 当桌面应用命中 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;
短篇小说
我有一个 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,因为桌面应用程序是不使用网络浏览器的不同环境
用户认证场景
- 桌面应用程序通过用户名和密码参数登录到 Web API
- 如果通过,则为经过身份验证的用户生成一个令牌并作为响应返回它
- 当桌面应用命中 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;