本文的上下文涉及 ASP.NET Web API 2.2 + OWIN 该环境是具有 OWIN 服务器和 Web Api 的单个应用程序。
背景:
在 Startup 类中,必须指定提供给 OAuthBearerAuthenticationProvider 的 OAuthBearerServerOptions。这些选项是在 OWIN 服务器启动期间创建的。在 OAuthBearerServerOptions 上,我必须指定 AccessTokenExpireTimeSpan,以便确保令牌过期。
问题
我必须能够在每个身份验证请求的基础上动态指定过期时间跨度。我不确定这是否可以做到,并且想知道:
启动配置内容:
var config = new HttpConfiguration();
WebApiConfig.Register(config);
var container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
var OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/OAuth"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(**THIS NEEDS TO BE DYNAMIC**)),
Provider = new AuthorizationServerProvider()
};
//STOP!!!!!!!!
//DO NOT CHANGE THE ORDER OF THE BELOW app.Use statements!!!!!
//Token Generation
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); //this MUST come before oauth registration
app.UseOAuthAuthorizationServer(OAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()
{
Provider = new BearerProvider()
});
app.UseAutofacMiddleware(container); //this MUST come before UseAutofacWebApi
app.UseAutofacWebApi(config);//this MUST come before app.UseWebApi
app.UseWebApi(config);
我开始搞乱 BearerProvider 类(请参阅上面的 app.UseOAuthBearerAuthentication 来了解我在哪里使用此类),特别是 ValidateIdentity 方法,但不确定这是否是身份验证工作流程中设置此值的正确点。这似乎是合适的,但我寻求证实我的立场。
public class BearerProvider : OAuthBearerAuthenticationProvider
{
public override async Task RequestToken(OAuthRequestTokenContext context)
{
await base.RequestToken(context);
//No token? attempt to retrieve from query string
if (String.IsNullOrEmpty(context.Token))
{
context.Token = context.Request.Query.Get("access_token");
}
}
public override Task ValidateIdentity(OAuthValidateIdentityContext context)
{
//context.Ticket.Properties.ExpiresUtc= //SOME DB CALL TO FIND OUT EXPIRE VALUE..IS THIS PROPER?
return base.ValidateIdentity(context);
}
}
提前致谢!
设置 context.Options.AccessTokenExpireTimeSpan 实际上会更改全局值,并影响所有请求,这不适用于原始需求。
正确的地方是TokenEndpoint方法。
public override Task TokenEndpoint(OAuthTokenEndpointContext context)
{
...
if (someCondition)
{
context.Properties.ExpiresUtc = GetExpirationDateFromDB();
}
...
}
所以我完全来错地方了。我最终要做的是使用我的自定义 OAuthorizationServerProvider 并在该自定义类中重写的 GrantResourceOwnerCredentials 方法中,我能够通过访问来设置超时值...
context.Options.AccessTokenExpireTimeSpan
财产。
<!-- language: c# -->
public class AuthorizationServerProvider : OAuthAuthorizationServerProvider
{
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
//DO STUFF
var expireValue=GetTimeOutFromSomeplace();
context.Options.AccessTokenExpireTimeSpan = expireValue;
//DO OTHER TOKEN STUFF
}
}
@dichen 的答案适用于大多数资助类型。对于已弃用的
implicit
授权类型(访问令牌直接从授权端点发出),永远不会调用 TokenEndpoint。虽然人们可能会找到一种通过重写 OAuthAuthorizationServerProvider.AuthorizeEndpoint 来更改令牌过期的方法(或者更好的是通过提供 OnAuthorizeEndpoint
Func),但我最终采用了一种不同的方法,我相信它可以解决 code
和 token
授予问题类型:
var options = new OAuthAuthorizationServerOptions
{
...
AccessTokenProvider = new AuthenticationTokenProvider
{
// see https://github.com/aspnet/AspNetKatana/issues/241
OnCreate = ctx => throw new NotImplementedException("In OAuth access token provider: "
+ "sync OnCreate is required by the framework, but unused in our case."),
OnCreateAsync = CreateAccessTokenAsync,
},
}
private async Task CreateAccessTokenAsync(AuthenticationTokenCreateContext context)
{
if (someCondition) {
context.Properties.ExpiresUtc = await GetExpirationDateFromDB();
}
}