您的问题是身份验证中间件在所有路由的请求管道上运行。需要为不同的请求配置不同的认证方式。
查看here 了解有关条件中间件的更多信息。
假设您的 api 通过api-key 标头进行身份验证,而您的常规应用通过 cookie 或不记名令牌进行身份验证。
在你的Startup.cs
// This will authenticate calling applications based on the "api-key" header
app.UseWhen(context => context.Request.Headers.ContainsKey("api-key"), appBuilder =>
{
appBuilder.UseMiddleware<HmacAuthentication>();
});
// Using the exact opposite, makes all other requests authenticate the normal way
app.UseWhen(context => !context.Request.Headers.ContainsKey("api-key"), appBuilder =>
{
appBuilder.UseAuthentication();
appBuilder.UseIdentityServer();
});
如果您修改您的 HmacAttribute 并将相同的代码放入某些中间件中,那么您有 2 个不同的身份验证路径,并且可以根据需要使用Authorize 属性或Policies。
您的中间件可能如下所示:
public class HmacAuthentication
{
private const string ApiKey = "api-key";
private RequestDelegate _next;
public ApiKeyMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
bool success = false;
string[] claims = null;
success = GetHeader(context.Request.Headers, out StringValues headerValue);
if (success)
{
success = ValidateKeyAndGetClaims(headerValue, out claims);
}
if (success)
{
context.User = GetPrincipal(headerValue, claims);
await _next(context);
}
else
{
context.Response.StatusCode = 401;
await context.Response.WriteAsync("Unauthorized");
}
}
internal bool GetHeader(IHeaderDictionary headers, out StringValues headerValue)
{
return headers.TryGetValue(ApiKey, out headerValue);
}
internal bool ValidateKeyAndGetClaims(string, headerValue, out string[] claims)
{
// Validate the api-key.
// Claims could depend on the key value or could be hardcoded
claims = new [] { "IsAuthenticated" };
return true;
}
internal ClaimsPrincipal GetPrincipal(string apiKey, string[] claims)
{
var identity = new ClaimsIdentity();
identity.AddClaim(new Claim(ClaimTypes.Name, apiKey));
if (claims != null)
{
foreach(var claim in claims)
{
identity.AddClaim(new Claim(claim, string.Empty));
}
}
return new ClaimsPrincipal(identity);
}
}