gpt4 book ai didi

c# - ASP.Net Core MVC/API/SignalR - 更改身份验证方案(Cookie 和 JWT)

转载 作者:行者123 更新时间:2023-11-30 21:30:51 25 4
gpt4 key购买 nike

我有一个 .Net Core 2.2 Web 应用程序 MVC,我在其中添加了 API Controller 和 SignalR 集线器。另一方面,我有一个调用集线器方法的移动应用程序。在从应用程序调用集线器之前,我通过 API 调用对我的用户进行身份验证 - 取回 JWT token - 并将此 token 用于 future 的请求,这样我就可以使用 Context.User.Identity.Name在我的中心方法中:

public static async Task<string> GetValidToken(string userName, string password)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(_API_BASE_URI);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

LoginViewModel loginVM = new LoginViewModel() { Email = userName, Password = password, RememberMe = false };
var formContent = Newtonsoft.Json.JsonConvert.SerializeObject(loginVM);
var content = new StringContent(formContent, Encoding.UTF8, "application/json");
HttpResponseMessage responseMessage;
try
{
responseMessage = await client.PostAsync("/api/user/authenticate", content);
var responseJson = await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false); ;
var jObject = JObject.Parse(responseJson);
_TOKEN = jObject.GetValue("token").ToString();
return _TOKEN;
}catch
[...]

然后使用 token :

_connection = new HubConnectionBuilder().WithUrl(ApiCommunication._API_BASE_URI + "/network", options =>
{
options.AccessTokenProvider = () => Task.FromResult(token);
}).Build();

到目前为止一切顺利。它在我的移动应用程序上按预期工作。但为了让它工作,我必须在服务器端设置这段代码 (Startup.cs):

services.AddAuthentication(options =>
{
options .DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options .DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
...

这使我无法再使用 cookie 身份验证,因此 mvc 网络应用程序不再按预期工作,因为它无法在请求中获取当前经过身份验证的用户。

删除行:

options .DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options .DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

使网络应用程序正常工作,但不再是移动应用程序(由于 Context.User.Identity.Name 等于 null,集线器调用失败)。

我一直在四处寻找如何处理不同的方案(在我的例子中是 cookie + jwt),据我所知,这在设计上是不可能的了。

是否有任何可能的解决方法来使用双重方案,或者我是否遗漏了什么?

我想也许我应该托管 2 个独立的项目,一个使用 Cookie 身份验证,另一个使用 JWT?

提前致谢。

最佳答案

有多种方法可以解决您遇到的问题,但首先让我们了解一下它目前无法正常工作的原因。

什么DefaultAuthenticateScheme意味着

当您为 DefaultAuthenticateScheme 设置一个值时AuthenticationOptions的属性(property),您指示身份验证中间件尝试针对该特定方案对每个 HTTP 请求进行身份验证。我将假设您正在使用 ASP.NET Identity 进行基于 cookie 的身份验证,并且当您调用 AddIdentity 时,它将cookie认证方案注册为默认认证方案;你可以在 source code on GitHub 中看到这个.

但是,这并不意味着您不能在您的应用程序中使用任何其他身份验证方案。

授权系统默认策略

如果您的应用程序的所有 protected 端点都可以被使用 cookie 或 JWT 进行身份验证的客户端访问,一种选择是使用授权系统默认策略。当您使用 AuthorizeAttribute 的“空”实例时,将使用该特殊策略类——作为装饰 Controller / Action 的属性,或者在应用程序级别全局使用 new AuthorizeFilter(new AuthorizeAttribute()) .

默认策略设置为只需要经过身份验证的用户,但没有定义需要“尝试”哪些身份验证方案来验证请求。结果是它依赖于已经执行的身份验证过程。它解释了您遇到的行为,其中一次只有 2 个方案中的一个起作用。

我们可以用一些代码更改默认策略:

services.AddAuthorization(options =>
{
options.DefaultPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddAuthenticationSchemes("<your-cookie-authentication-scheme", "your-jwt-authentication-scheme")
.Build();
})

具体授权政策

如果您发现自己需要某些端点只能由使用 cookie 进行身份验证的客户端访问,而其他使用 JWT 的客户端可以访问,则可以利用授权策略。

它们的工作方式与默认策略完全相同,希望您可以根据端点选择适用的策略。您可以像这样添加策略:

services.AddAuthorization(options =>
{
options.AddPolicy("Cookies", new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddAuthenticationSchemes("<your-cookie-authentication-scheme")
.Build());

options.AddPolicy("JWT", new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddAuthenticationSchemes("<your-jwt-authentication-scheme")
.Build());
})

然后,您可以通过使用 [Authorize(Policy = "<policy-name>")] 装饰它们来在适当的端点中引用这些策略。 .作为旁注,如果您的策略之间的唯一区别是身份验证方案,则可以在不创建策略并引用 [Authorize] 中的适当身份验证方案的情况下实现相同的结果。属性与 AuthenticationSchemes属性(property)。

当您有更复杂的规则时,政策很有值(value),例如,特定声明需要此特定值

希望这对您有所帮助,让我知道您的进展情况! 👍

关于c# - ASP.Net Core MVC/API/SignalR - 更改身份验证方案(Cookie 和 JWT),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53937191/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com