- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 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/
我有一个自定义的基于策略的授权处理程序,定义如下。身份验证是在用户点击此应用程序之前处理的,因此我只需要授权。我收到错误: No authenticationScheme was specified,
我有一个简单的 JWT 身份验证示例,您可以在其中找到它 here services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
我使用 identityserver4 中间件创建了一个基本的核心应用程序。我已经在数据库中设置了资源和客户端。我还添加了用于签名消息的自签名证书。 IdentityServer4 似乎运行正常,但我
我们有一个 Net Core 2.1 API 项目。我们使用请求 header 来检索 API key ,我们根据数据库检查该 key 是否与预期 key 之一匹配。如果是,那么我们允许请求继续,否则
我正在使用以下代码在 ASP.NET Core 2.0 中使用 cookie 进行身份验证 services .AddAuthentication(CookieAuthenticationDe
Spring oauth2 中有 setClientAuthenticationScheme() 和 setAuthenticationScheme()。 据我所知,ClientAuthenticat
我尝试按照本指南在 .NET core 2 中运行测试时允许用户登录 http://geeklearning.io/how-to-deal-with-identity-when-testing-an-
我正在使用 ASP.NET Core 2.1 WebApi 项目,因为我们使用了基于 token 的身份验证 public class UserIdentityFilter : IAuthorizat
这个问题在这里已经有了答案: No authenticationScheme was specified, and there was no DefaultChallengeScheme found
这个问题在这里已经有了答案: No authenticationScheme was specified, and there was no DefaultChallengeScheme found
我正在尝试将 ASP.NET Core 1.1 应用程序迁移到 ASP.NET Core 2.0。 该应用程序相当简单,涉及以下内容: 托管在 HttpSys(以前称为 WebListener)上 使
我有一个使用 Aurelia 作为前端并使用 ASP.NET Core 作为其 Web API 的应用程序。 我必须在我的 Web API 周围设置一些身份验证和授权。为此,我正在尝试使用 OAuth
我是一名优秀的程序员,十分优秀!