问题描述
我正在尝试通过Owin实现OAuth承载身份验证.当传递了无效或过期的令牌时,默认实现是将其记录为警告,而只是不设置身份.但是,在这种情况下,我想以错误拒绝整个请求.但是我该怎么办呢?
I'm trying to implement OAuth Bearer Authentication with Owin. When an invalid or expired token is passed, the default implementation is to log this as a warning and just don't set an Identity. I however would like to reject the whole request with an error in this case. But how would I do this?
仔细研究代码后,我发现在OAuthBearerAuthenticationHandler
中,当提供的AuthenticationTokenProvider
没有解析任何票证时(如默认实现),它将使用回退机制来解析令牌.当令牌无法解析为任何票证或令牌过期时,此处理程序将记录警告.
After digging through the code I found out that in OAuthBearerAuthenticationHandler
it will parse the token using a fallback mechanism when the provided AuthenticationTokenProvider
did not parse any ticket (like the default implementation). This handler will log a warning when the token could not be parsed to any ticket or when it expired.
但是我找不到任何地方可以插入我自己的逻辑,以了解令牌无效或过期时发生的情况.从理论上讲,我可以自己在AuthenticationTokenProvider
中进行检查,但是随后我将不得不重新实现用于创建和读取令牌的逻辑(=复制过来).同样,这似乎不合适,因为此类似乎仅负责创建和解析令牌.我也看不到在OAuthBearerAuthenticationMiddleware
中插入自己的OAuthBearerAuthenticationHandler
实现的方法.
But I can't find any place to plug in my own logic to what happens when the token is invalid or expired. I could theoretically check this on my own in the AuthenticationTokenProvider
, but then I would have to reimplement the logic (= copy it over) for creating and reading the token. Also this seems just out of place, as this class seems to be only responsible for creating and parsing tokens. I also don't see a way to plug in my own implementation of the OAuthBearerAuthenticationHandler
in the OAuthBearerAuthenticationMiddleware
.
显然,我最好,最简洁的方法是重新实现整个中间件,但这似乎也太过分了.
Apparently my best and cleanest shot would be to reimplement the whole middleware, but this also seems very overkill.
我忽略了什么?我将如何做到最好呢?
What do I overlook? How would I go on about this the best?
为澄清.我知道,通过不设置身份,该请求将在以后的Web API中被401 Unauthorized拒绝.但是我个人认为这是一种非常糟糕的风格,在没有任何通知的情况下默默地吞下了错误的访问令牌.这样,您就不会知道令牌是废话,而只是知道自己未被授权.
For clarification. I know by not setting an identity the request will be rejected with 401 Unauthorized later in the Web API. But I personally see this as really bad style, silently swallowing an erroneous access token without any notification. This way you don't get to know that your token is crap, you just get to know you're not authorized.
推荐答案
我有一个类似的问题,我认为答案很晚,但是有人会来这里遇到类似的问题:
I had a similar issue, i think the answer is to late but someone will come here with a similar problem:
我使用此nuget包进行验证身份验证,但我认为任何方法都可以帮助您: https://www.nuget.org/packages/WebApi.AuthenticationFilter .您可以在此站点 https://github.com/mbenford/WebApi-AuthenticationFilter 中阅读其文档.
I used this nuget package for validate authentication, but i think any method can help: https://www.nuget.org/packages/WebApi.AuthenticationFilter. You can read its documentation in this site https://github.com/mbenford/WebApi-AuthenticationFilter
AuthenticationFilter.cs
AuthenticationFilter.cs
public class AuthenticationFilter : AuthenticationFilterAttribute{
public override void OnAuthentication(HttpAuthenticationContext context)
{
System.Net.Http.Formatting.MediaTypeFormatter jsonFormatter = new System.Net.Http.Formatting.JsonMediaTypeFormatter();
var ci = context.Principal.Identity as ClaimsIdentity;
//First of all we are going to check that the request has the required Authorization header. If not set the Error
var authHeader = context.Request.Headers.Authorization;
//Change "Bearer" for the needed schema
if (authHeader == null || authHeader.Scheme != "Bearer")
{
context.ErrorResult = context.ErrorResult = new AuthenticationFailureResult("unauthorized", context.Request,
new { Error = new { Code = 401, Message = "Request require authorization" } });
}
//If the token has expired the property "IsAuthenticated" would be False, then set the error
else if (!ci.IsAuthenticated)
{
context.ErrorResult = new AuthenticationFailureResult("unauthorized", context.Request,
new { Error = new { Code = 401, Message = "The Token has expired" } });
}
}}
AuthenticationFailureResult.cs
AuthenticationFailureResult.cs
public class AuthenticationFailureResult : IHttpActionResult{
private object ResponseMessage;
public AuthenticationFailureResult(string reasonPhrase, HttpRequestMessage request, object responseMessage)
{
ReasonPhrase = reasonPhrase;
Request = request;
ResponseMessage = responseMessage;
}
public string ReasonPhrase { get; private set; }
public HttpRequestMessage Request { get; private set; }
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
return Task.FromResult(Execute());
}
private HttpResponseMessage Execute()
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
System.Net.Http.Formatting.MediaTypeFormatter jsonFormatter = new System.Net.Http.Formatting.JsonMediaTypeFormatter();
response.Content = new System.Net.Http.ObjectContent<object>(ResponseMessage, jsonFormatter);
response.RequestMessage = Request;
response.ReasonPhrase = ReasonPhrase;
return response;
}}
响应示例:
{"Error":{"Code":401,"Message":"Request require authorization"}}
{"Error":{"Code":401,"Message":"The Token has expired"}}
字体和灵感文档:
///github.com/mbenford/WebApi-AuthenticationFilter
//github.com/mbenford/WebApi-AuthenticationFilter
//www.asp.net/web-api/overview/security/authentication-filters
//www.asp.net/web-api/overview/security/authentication-filters
这篇关于无效或过期令牌返回错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!