gpt4 book ai didi

c# - 没有指定 authenticationScheme,也没有找到 DefaultChallengeScheme - ASP.NET core 2.1

转载 作者:行者123 更新时间:2023-11-30 14:45:42 26 4
gpt4 key购买 nike

我正在使用 ASP.NET Core 2.1 WebApi 项目,因为我们使用了基于 token 的身份验证

public class UserIdentityFilter : IAuthorizationFilter
{
public void OnAuthorization(AuthorizationFilterContext context)
{
StringValues authorizationHeaders;
if (!context.HttpContext.Request.Headers.TryGetValue("Authorization", out authorizationHeaders))
return;
...
...
}
}

还有用于错误处理的中间件:

public async Task Invoke(HttpContext context, ILogger logger, IAppConfiguration appConfiguration)
{
try
{
await _next(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex, logger, appConfiguration);
}
}

如果我为授权方法传递 header ,它工作正常,但是缺少相同的 header 会产生错误没有指定 authenticationScheme,也没有找到 DefaultChallengeScheme。

这里我有两个问题:

1) 在未指定 header 的情况下,可以向用户端发送 500 异常吗?

2) 如何处理这种情况并传递有意义的消息“header is missing”之类的?

最佳答案

It is okay to send 500 with this exception to user end, when header not specified?

恐怕这不是个好主意。

500 状态代码表示存在服务器错误。当客户端发送没有 token 的请求时,告诉客户端“发生内部错误”是没有意义的。更好的方法是发送401来挑战用户或者发送403来禁止。

How to handle this scenario and passing meaningful message "header is missing" or something?

首先,我不得不说我不认为使用 AuthorizationFilter 来验证用户是一个好的选择。

如错误所述,引发错误是因为未指定 AuthenticationScheme,并且未找到 DefaultChallengeScheme

要修复该错误,只需指定一个身份验证方案。例如,如果您正在使用 JwtToken,您应该添加一个 AddAuthentication(JwtBearerDefaults.AuthenticationScheme) 或使用一个 [Authorize(AuthenticationSchemes ="JwtBearerDefaults.AuthenticationScheme")] 属性

否则,如果您想自定义它对用户进行身份验证的方式(例如,自定义基于 token 的身份验证),您应该创建一个新的 token 身份验证处理程序。已经有一个内置的抽象 AuthenticationHandler 类:

public abstract class AuthenticationHandler<TOptions> : IAuthenticationHandler 
where TOptions : AuthenticationSchemeOptions, new()
{
// ...
}

由于默认的 HandleChallengeAsync() 将发送一个 401 响应,您可以简单地扩展 AuthenticationHandler 并覆盖 >HandleChallengeAsync() 自定义您自己的消息以挑战用户的方法 :

public class OurOwnAuthenticationHandler : AuthenticationHandler<ApiKeyAuthOpts>
{
public OurOwnAuthenticationHandler(IOptionsMonitor<ApiKeyAuthOpts> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
: base(options, logger, encoder, clock)
{
}


protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
StringValues authorizationHeaders;
if (!context.HttpContext.Request.Headers.TryGetValue("Authorization", out authorizationHeaders))
return AuthenticateResult.NoResult();
// ... return AuthenticateResult.Fail(exceptionMessage);
// ... return AuthenticateResult.Success(ticket)
}

protected override Task HandleChallengeAsync(AuthenticationProperties properties)
{
Response.StatusCode = 401;
var message = "tell me your token";
Response.Body.Write(Encoding.UTF8.GetBytes(message));
return Task.CompletedTask;
}

protected override Task HandleForbiddenAsync(AuthenticationProperties properties)
{
Response.StatusCode = 403;
var message = "you have no rights";
Response.Body.Write(Encoding.UTF8.GetBytes(message));
return Task.CompletedTask;
}

}

最后,您还需要注册身份验证处理程序:

services.AddAuthentication("OurOwnAuthN")
.AddScheme<OurOwnAuthNOpts,OurOwnAuthNHandler>("OurOwnAuthN","Our Own AuthN Scheme",opts=>{
// ...
});

如果您不想将“OurOwnAuthN”设置为默认身份验证方案,您可以使用[Authorize(AuthenticationSchemes ="OurOwnAuthN")]来保护您的资源:

// your `ConfigureServices()`
services.AddAuthentication()
.AddScheme<OurOwnAuthNOpts,OurOwnAuthNHandler>("OurOwnAuthN","Our Own AuthN Scheme",opts=>{
// ...
});


// your action method :
// GET api/values/5
[Authorize(AuthenticationSchemes ="OurOwnAuthN")]
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
return "value";
}

如果用户发送没有 token 或 token 不正确的请求,服务器的响应将是:

HTTP/1.1 401 Unauthorized
Transfer-Encoding: chunked
Server: Kestrel
X-SourceFiles: =?UTF-8?B?RDpccmVwb3J0XDIwMThcMTBcMThcU08uYXV0aGVudGljYXRpb25TY2hlbWUsIE5vIERlZmF1bHRDaGFsbGVuZ2VTY2hlbWVcQXBwXEFwcFxhcGlcdmFsdWVzXDE=?=
X-Powered-By: ASP.NET

tell me your token

[编辑]

如果你使用的是 Jwt Token ,你可以使用下面的代码来注册 JwtBearer Authentication :

services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["Jwt:Issuer"],
ValidAudience = Configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
};
});

[编辑2]

JwtBearer AuthenticationHandler 提供了一个Challenge来自定义WWW-Authenticate:

    .AddJwtBearer(options => {
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["Jwt:Issuer"],
ValidAudience = Configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
};
options.Challenge ="tell me your token";;
})

响应将是:

HTTP/1.1 401 Unauthorized
Server: Kestrel
WWW-Authenticate: tell me your token, error="invalid_token"
X-SourceFiles: =?UTF-8?B?RDpccmVwb3J0XDIwMThcMTBcMThcU08uYXV0aGVudGljYXRpb25TY2hlbWUsIE5vIERlZmF1bHRDaGFsbGVuZ2VTY2hlbWVcQXBwXEFwcFxhcGlcdmFsdWVzXDE=?=
X-Powered-By: ASP.NET
Content-Length: 0

注意 WwW-Authenticate header 。

另一种方法是通过以下方式转发挑战:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options => {
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["Jwt:Issuer"],
ValidAudience = Configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
};
options.ForwardChallenge = "OurOwnAuthN";
})
.AddScheme<OurOwnAuthNOpts,OurOwnAuthNHandler>("OurOwnAuthN","Our Own Authentication Scheme",opts=>{
// ...
});

响应将是:

HTTP/1.1 401 Unauthorized
Transfer-Encoding: chunked
Server: Kestrel
X-SourceFiles: =?UTF-8?B?RDpccmVwb3J0XDIwMThcMTBcMThcU08uYXV0aGVudGljYXRpb25TY2hlbWUsIE5vIERlZmF1bHRDaGFsbGVuZ2VTY2hlbWVcQXBwXEFwcFxhcGlcdmFsdWVzXDE=?=
X-Powered-By: ASP.NET

tell me your token

关于c# - 没有指定 authenticationScheme,也没有找到 DefaultChallengeScheme - ASP.NET core 2.1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52854049/

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