- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我们有一个 Net Core 2.1 API 项目。我们使用请求 header 来检索 API key ,我们根据数据库检查该 key 是否与预期 key 之一匹配。如果是,那么我们允许请求继续,否则我们要发回未经授权的响应。
我们的 startup.cs
services.AddAuthorization(options =>
{
options.AddPolicy("APIKeyAuth", policyCorrectUser =>
{
policyCorrectUser.Requirements.Add(new APIKeyAuthReq());
});
});
services.AddSingleton<Microsoft.AspNetCore.Authorization.IAuthorizationHandler, APIKeyAuthHandler>();
我们的 APIKeyAuthHandler.cs
public class APIKeyAuthReq : IAuthorizationRequirement { }
public class APIKeyAuthHandler : AuthorizationHandler<APIKeyAuthReq>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, APIKeyAuthReq requirement)
{
if (context == null)
throw new ArgumentNullException(nameof(context));
if (requirement == null)
throw new ArgumentNullException(nameof(requirement));
var httpContext = context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext;
var headers = httpContext.HttpContext.Request.Headers;
if (headers.TryGetValue("Authorization", out Microsoft.Extensions.Primitives.StringValues value))
{
using (DBContext db = new DBContext ())
{
var token = value.First().Split(" ")[1];
var login = db.Login.FirstOrDefault(l => l.Apikey == token);
if (login == null)
{
context.Fail();
httpContext.HttpContext.Response.StatusCode = 403;
return Task.CompletedTask;
} else
{
httpContext.HttpContext.Items.Add("CurrentUser", login);
context.Succeed(requirement);
return Task.CompletedTask;
}
}
}
}
}
和我们的controller.cs
[Route("api/[controller]/[action]")]
[Authorize("APIKeyAuth")]
[ApiController]
public class SomeController : ControllerBase
{
}
当有效 key 存在时一切正常,但当它不存在时,将抛出 500 内部错误,而不是 403,而不是 No authenticationScheme。
我们是 net core 的新手(来自 Net Framework/Forms Authentication),所以如果有更准确的方法来进行这种身份验证,请告诉我。
错误信息:
InvalidOperationException: No authenticationScheme was specified, and there was no DefaultChallengeScheme found. Microsoft.AspNetCore.Authentication.AuthenticationService.ChallengeAsync(HttpContext context, string scheme, AuthenticationProperties properties)
最佳答案
首选基于 token 的身份验证。但是,如果您确实需要自定义 ApiKeyAuth
方案,那么,这是可能的。
首先,Authorize("APIKeyAuth")
在这里似乎没有意义,因为我们必须在授权前对用户进行身份验证。当有传入请求时,服务器不知道用户是谁。因此,让我们将 ApiKeyAuth
从 Authorization
移至 Authentication
。
为此,只需创建一个可用于保存选项的虚拟 ApiKeyAuthOpts
public class ApiKeyAuthOpts : AuthenticationSchemeOptions
{
}
和一个简单的 ApiKeyAuthHandler
来处理身份验证(我只是复制了上面的一些代码):
public class ApiKeyAuthHandler : AuthenticationHandler<ApiKeyAuthOpts>
{
public ApiKeyAuthHandler(IOptionsMonitor<ApiKeyAuthOpts> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
: base(options, logger, encoder, clock)
{
}
private const string API_TOKEN_PREFIX = "api-key";
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
string token = null;
string authorization = Request.Headers["Authorization"];
if (string.IsNullOrEmpty(authorization)) {
return AuthenticateResult.NoResult();
}
if (authorization.StartsWith(API_TOKEN_PREFIX, StringComparison.OrdinalIgnoreCase)) {
token = authorization.Substring(API_TOKEN_PREFIX.Length).Trim();
}
if (string.IsNullOrEmpty(token)) {
return AuthenticateResult.NoResult();
}
// does the token match ?
bool res =false;
using (DBContext db = new DBContext()) {
var login = db.Login.FirstOrDefault(l => l.Apikey == token); // query db
res = login ==null ? false : true ;
}
if (!res) {
return AuthenticateResult.Fail($"token {API_TOKEN_PREFIX} not match");
}
else {
var id=new ClaimsIdentity(
new Claim[] { new Claim("Key", token) }, // not safe , just as an example , should custom claims on your own
Scheme.Name
);
ClaimsPrincipal principal=new ClaimsPrincipal( id);
var ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), Scheme.Name);
return AuthenticateResult.Success(ticket);
}
}
}
最后,我们还需要一些配置来让它们工作:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddAuthentication("ApiKeyAuth")
.AddScheme<ApiKeyAuthOpts,ApiKeyAuthHandler>("ApiKeyAuth","ApiKeyAuth",opts=>{ });
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// ...
app.UseAuthentication();
app.UseHttpsRedirection();
app.UseMvc();
}
当您向受 [Authorize]
保护的操作方法发送请求时:
GET https://localhost:44366/api/values/1 HTTP/1.1
Authorization: api-key xxx_yyy_zzz
响应将是 HTTP/1.1 200 OK
。当您发送没有正确 key 的请求时,响应将是:
HTTP/1.1 401 Unauthorized
Server: Kestrel
X-SourceFiles: =?UTF-8?B?RDpccmVwb3J0XDIwMThcOVw5LTEyXFNPLkFwaUtleUF1dGhcQXBwXEFwcFxhcGlcdmFsdWVzXDE=?=
X-Powered-By: ASP.NET
Date: Wed, 12 Sep 2018 08:33:23 GMT
Content-Length: 0
关于c# - InvalidOperationException : No authenticationScheme was specified, 并且没有找到 DefaultChallengeScheme,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52287542/
我有一个自定义的基于策略的授权处理程序,定义如下。身份验证是在用户点击此应用程序之前处理的,因此我只需要授权。我收到错误: 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
我是一名优秀的程序员,十分优秀!