Web API OAUTH - 区分标识令牌是否过期或未经授权
Web API OAUTH - Distinguish between if Identify Token Expired or UnAuthorized
目前正在使用 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(未授权)。正在使用 Fiddler 检查。
我如何向用户发送自定义消息,说明您的令牌已过期。我需要重写哪个函数或模块。
我的另一个问题是下面这行有什么用?
app.UseOAuthBearerAuthentication(新的 OAuthBearerAuthenticationOptions());
我真的需要这个来实现吗,因为当我检查它仍然可以在没有上述行的情况下工作。是否存在安全违规?
您不能直接自定义过期令牌的行为,但可以使用自定义中间件来实现。
首先覆盖 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(未授权)的形式出现,即使是那些具有有效令牌的请求。
目前正在使用 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(未授权)。正在使用 Fiddler 检查。
我如何向用户发送自定义消息,说明您的令牌已过期。我需要重写哪个函数或模块。
我的另一个问题是下面这行有什么用?
app.UseOAuthBearerAuthentication(新的 OAuthBearerAuthenticationOptions()); 我真的需要这个来实现吗,因为当我检查它仍然可以在没有上述行的情况下工作。是否存在安全违规?
您不能直接自定义过期令牌的行为,但可以使用自定义中间件来实现。
首先覆盖 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(未授权)的形式出现,即使是那些具有有效令牌的请求。