Web API OAUTH - 区分Identify Token Expired或UnAuthorized

时间:2015-08-24 11:03:31

标签: oauth asp.net-web-api2 owin

目前正在使用Owin,Oauth,Claims。开发授权服务器。

以下是我的Oauth配置,我有2个问题

 OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
  {

     AllowInsecureHttp = true,
     TokenEndpointPath = new PathString("/token"),
     AccessTokenExpireTimeSpan = TimeSpan.FromSeconds(1000),
     Provider = new AuthorizationServerProvider()
     //RefreshTokenProvider = new SimpleRefreshTokenProvider()
  };
     app.UseOAuthAuthorizationServer(OAuthServerOptions);
     app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

如果令牌过期且用户使用过期的令牌用户访问 401(unAuthorized)。使用Fiddler进行检查。

如何向用户发送自定义消息,说明您的令牌已过期。我需要覆盖哪个功能或模块。

我的另一个问题是下面这行的用途是什么?

app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); 我是否真的需要这个来实现,因为当我检查它仍然没有上述行。任何安全违规行为?

1 个答案:

答案 0 :(得分:6)

您无法直接自定义过期令牌的行为,但您可以使用自定义中间件来执行此操作。

首先覆盖AuthenticationTokenProvider,以便您可以在身份验证票据过期之前拦截它。

public class CustomAuthenticationTokenProvider : AuthenticationTokenProvider
{
    public override void Receive(AuthenticationTokenReceiveContext context)
    {
        context.DeserializeTicket(context.Token);

        if (context.Ticket != null &&
            context.Ticket.Properties.ExpiresUtc.HasValue &&
            context.Ticket.Properties.ExpiresUtc.Value.LocalDateTime < DateTime.Now)
        {
            //store the expiration in the owin context so that we can read it later a middleware
            context.OwinContext.Set("custom.ExpriredToken", true);
        }
    }
}

并在Startup中配置它以及一个小型自定义中间件

using AppFunc = System.Func<System.Collections.Generic.IDictionary<string, object>, System.Threading.Tasks.Task>;

app.UseOAuthAuthorizationServer(OAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()
{
    AccessTokenProvider = new CustomAuthenticationTokenProvider()
});

//after the request has been authenticated or not
//check for our custom env setting and act accordingly
app.Use(new Func<AppFunc, AppFunc>(next => (env) =>
{
    var ctx = new OwinContext(env);
    if (ctx.Get<bool>("custom.ExpriredToken"))
    {
        //do wathever you want with the response
        ctx.Response.StatusCode = 401;
        ctx.Response.ReasonPhrase = "Token exprired";

        //terminate the request with this middleware
        return Task.FromResult(0);
    }
    else
    {
        //proceed with the rest of the middleware pipeline
        return next(env);
    }
}));

如果您注意到我在调用UseOAuthBearerAuthentication之后放置了自定义中间件,这很重要,并且源于您对第二个问题的回答。

OAuthBearerAuthenticationMidlleware负责身份验证,但不负责授权。所以它只是读取令牌并填写信息,以便稍后在管道中使用IAuthenticationManager访问它。

所以是的,无论有没有,您的所有请求都将以401(未经授权)的形式出现,即使是那些有效令牌。