DelegatingHandler 添加授权令牌到请求
DelegatingHandler to add Authorization token to request
为了下载文件,我需要使用 GET: /API/File/ID?bearerToken=XYZ... 方法。
我已经创建了一个 DelegatingHandler 来将我的令牌添加到 AuthorizationHeader,但似乎令牌验证可能在此之前完成...
当前的所有令牌由 Angular 在请求前将令牌添加到 HTTP header 添加。
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
ConfigureOAuth(app);
WebApiConfig.Register(config);
GlobalFilters.Add(config);
app.UseWebApi(config);
config.MessageHandlers.Insert(0, new QueryStringBearerToken());
}
..
public class QueryStringBearerToken : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
var bearerToken = request.GetQueryNameValuePairs().
Where(kvp => kvp.Key == "bearertoken")
.Select(kvp => kvp.Value)
.FirstOrDefault();
//QueryString exists and Header doesn't
if (!string.IsNullOrWhiteSpace(bearerToken) && !request.Headers.Any(x=>x.Key == "Authorization"))
{
request.Headers.Add("Authorization", "Bearer " + bearerToken);
}
return base.SendAsync(request, cancellationToken);
}
}
我猜你正在使用 Katana 的 Bearer 中间件? (根据您对 ConfigureAuth
的调用判断?)
如果是这样,Katana 中间件确实会在 Web API 处理程序之前 运行 并在它有机会被处理程序处理之前拒绝您的请求。
您应该将功能移至 Katana 中间件,而不是创建处理程序。
这是一个例子:
public class QueryBearerMiddleware : OwinMiddleware
{
public QueryBearerMiddleware(OwinMiddleware next)
: base(next)
{
}
public override async Task Invoke(IOwinContext context)
{
string bearerToken = null;
if (context.Request.QueryString.HasValue)
{
var queryPairs = context.Request.QueryString.ToUriComponent()
.Substring(1)
.Split(new [] {'&'}, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Split('=')).ToDictionary(x => x[0], x => x[1]);
if (queryPairs.ContainsKey("bearertoken"))
{
bearerToken = queryPairs["bearertoken"];
}
}
//QueryString exists and Header doesn't
if (!string.IsNullOrWhiteSpace(bearerToken) && context.Request.Headers.All(x => x.Key != "Authorization"))
{
context.Request.Headers.Add("Authorization", new [] { "Bearer " + bearerToken });
}
await Next.Invoke(context);
}
}
您应该在 Bearer 中间件之前运行注册这个中间件。
在您的 ConfigureAuth
中的某处,您应该可以调用 app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
。我们刚刚创建的这个新中间件,应该在之前注册,即:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.Use(typeof(QueryBearerMiddleware));
var config = new HttpConfiguration();
ConfigureOAuth(app);
WebApiConfig.Register(config);
GlobalFilters.Add(config);
app.UseWebApi(config);
}
}
为了下载文件,我需要使用 GET: /API/File/ID?bearerToken=XYZ... 方法。
我已经创建了一个 DelegatingHandler 来将我的令牌添加到 AuthorizationHeader,但似乎令牌验证可能在此之前完成...
当前的所有令牌由 Angular 在请求前将令牌添加到 HTTP header 添加。
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
ConfigureOAuth(app);
WebApiConfig.Register(config);
GlobalFilters.Add(config);
app.UseWebApi(config);
config.MessageHandlers.Insert(0, new QueryStringBearerToken());
}
..
public class QueryStringBearerToken : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
var bearerToken = request.GetQueryNameValuePairs().
Where(kvp => kvp.Key == "bearertoken")
.Select(kvp => kvp.Value)
.FirstOrDefault();
//QueryString exists and Header doesn't
if (!string.IsNullOrWhiteSpace(bearerToken) && !request.Headers.Any(x=>x.Key == "Authorization"))
{
request.Headers.Add("Authorization", "Bearer " + bearerToken);
}
return base.SendAsync(request, cancellationToken);
}
}
我猜你正在使用 Katana 的 Bearer 中间件? (根据您对 ConfigureAuth
的调用判断?)
如果是这样,Katana 中间件确实会在 Web API 处理程序之前 运行 并在它有机会被处理程序处理之前拒绝您的请求。
您应该将功能移至 Katana 中间件,而不是创建处理程序。
这是一个例子:
public class QueryBearerMiddleware : OwinMiddleware
{
public QueryBearerMiddleware(OwinMiddleware next)
: base(next)
{
}
public override async Task Invoke(IOwinContext context)
{
string bearerToken = null;
if (context.Request.QueryString.HasValue)
{
var queryPairs = context.Request.QueryString.ToUriComponent()
.Substring(1)
.Split(new [] {'&'}, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Split('=')).ToDictionary(x => x[0], x => x[1]);
if (queryPairs.ContainsKey("bearertoken"))
{
bearerToken = queryPairs["bearertoken"];
}
}
//QueryString exists and Header doesn't
if (!string.IsNullOrWhiteSpace(bearerToken) && context.Request.Headers.All(x => x.Key != "Authorization"))
{
context.Request.Headers.Add("Authorization", new [] { "Bearer " + bearerToken });
}
await Next.Invoke(context);
}
}
您应该在 Bearer 中间件之前运行注册这个中间件。
在您的 ConfigureAuth
中的某处,您应该可以调用 app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
。我们刚刚创建的这个新中间件,应该在之前注册,即:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.Use(typeof(QueryBearerMiddleware));
var config = new HttpConfiguration();
ConfigureOAuth(app);
WebApiConfig.Register(config);
GlobalFilters.Add(config);
app.UseWebApi(config);
}
}