在 WebAPI 的查询字符串中传递和验证 OWIN Bearer 令牌
Posted
技术标签:
【中文标题】在 WebAPI 的查询字符串中传递和验证 OWIN Bearer 令牌【英文标题】:Passing and verifying the OWIN Bearer token in Query String in WebAPI 【发布时间】:2014-03-22 10:23:00 【问题描述】:短版: 我需要将 OWIN 轴承令牌作为查询参数而不是在请求标头中传递和验证。
然后如何根据该令牌字符串获取授权方法?
背景: 我想调用 webapi 方法将文件下载为流(并且不希望用户从已知文件位置下载它)。
如果我还需要设置自定义请求标头(即不记名令牌),我无法使其工作。
我应该能够在查询字符串中传递令牌 - 但不知道如何获取该令牌然后对用户进行身份验证。
我需要过滤吗?我需要特殊索赔等吗? webapi方法是否需要包含“access_token”作为函数参数之一?
【问题讨论】:
【参考方案1】:我在这里写过它是如何工作的: http://leastprivilege.com/2013/10/31/retrieving-bearer-tokens-from-alternative-locations-in-katanaowin/
【讨论】:
【参考方案2】:为了完整起见,here's 另一个巧妙的解决方案。
摘录:
app.Use(async (context, next) =>
if (context.Request.QueryString.HasValue)
if (string.IsNullOrWhiteSpace(context.Request.Headers.Get("Authorization")))
var queryString = HttpUtility.ParseQueryString(context.Request.QueryString.Value);
string token = queryString.Get("access_token");
if (!string.IsNullOrWhiteSpace(token))
context.Request.Headers.Add("Authorization", new[] string.Format("Bearer 0", token) );
await next.Invoke();
);
【讨论】:
非常感谢,我将它包含在我自己的 IAppBuilder 扩展方法中:public static void UseQueryStringAuthentication(this IAppBuilder app),以便我可以遵循与 app.UseQueryStringAuthentication() 相同的做法。还值得一提的是,当我们拦截调用时,我们必须在调用身份验证机制之前将其放入管道中。所以我把它作为我的 Startup.Auth 文件中的第一项。 这必须出现在调用 app.UseOAuthBearerTokens 之前 是的,非常重要,这是在 app.UseOAuthBearerTokens(OAuthOptions) 命令之前 这行得通,非常感谢。但有一个问题。假设用户生成一个 PDF 文件以供下载,其中包含资源链接(即“/downloads/file_id”)。这适用于您的方法,但令牌已过期。一段时间后,如果我尝试打开此 PDF 中的链接,它将再次未经授权。有什么想法可以解决这个问题吗? @Nexus 是的,包含不记名令牌的 URL 将过期。要么使用 401“未授权”响应来处理此问题,重定向到您的登录页面,然后可以使用新令牌重定向回 /downloads/... 链接。或者使用不安全的 API 来提供下载,但不是采用file_id
,您可以生成一个唯一令牌并通过您的数据库(或其他)将其与您的文件相关联,然后创建一个 /downloads/file_token
端点。这种解耦将通过混淆(即人们猜测文件 ID)保护您的 API,并允许您禁用/过期下载链接。【参考方案3】:
或者这样做
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
Authority = IdentityConfig.Authority,
RequiredScopes = new[] "api" ,
TokenProvider = new OAuthBearerAuthenticationProvider
OnRequestToken = ctx =>
if (String.IsNullOrWhiteSpace(ctx.Token) && ctx.Request.QueryString.HasValue)
NameValueCollection parsedQuery = HttpUtility.ParseQueryString(ctx.Request.QueryString.Value);
ctx.Token = parsedQuery["access_token"];
return Task.FromResult(0);
);
【讨论】:
以上是关于在 WebAPI 的查询字符串中传递和验证 OWIN Bearer 令牌的主要内容,如果未能解决你的问题,请参考以下文章
HttpClient 将 ClaimsIdentity 传递给另一个 WebApi