OWIN 在 OData $batch 请求上丢失身份

OWIN losing Identity on OData $batch requests

我正在尝试将我的标准 WebApi 应用移至 OWIN,但遇到了身份和 $batch 请求的问题。

我目前有一个 DelegatingHandler 可以检测并分配 SendAsync 中的身份:

// Detect bearer token and build the identity above.
IOwinContext owinContext = request.GetOwinContext();
owinContext.Authentication.User = new ClaimsPrincipal(identity);

对于正常请求,这会一直持续到 ODataController.User。但是在 $batch 上请求 属性 returns 到未经身份验证的 ClaimsIdentity.

甚至 GetOwinContext returns 一个 IOwinContext 没有任何用户。我假设它为每个批处理部分创建了一个新的上下文,但我看不到任何找到原始上下文的方法。

任何帮助都会很棒!

在您的 SendAsync 方法中尝试使用:

request.GetRequestContext().Principal = new ClaimsPrincipal(identity);

这将同时分配 Thread.CurrentPrincipal 和当前的 OWIN 上下文(检查此 link)。 我不是 100% 确定,但我的猜测是当前线程中未设置 Principal,因为 OData 在不同线程中执行 $batch 子请求,并且 OWIN 上下文丢失。

另一种选择是在 Configuration 方法中从 OWIN 中间件分配身份,而不是在 DelegatingHandler 中进行。这在这个答案中有解释:,这也与您的问题有某种关系。

希望对您有所帮助。

批处理的子请求在单独的线程中执行,并在这些请求中松散了身份验证主体。

在您的 DelegatingHandler 中试试这个。

var principal = new ClaimsPrincipal(identity);

System.Threading.Thread.CurrentPrincipal = principal;
if (System.Web.HttpContext.Current != null) {
    System.Web.HttpContext.Current.User = principal;
}

// Detect bearer token and build the identity above.
IOwinContext owinContext = request.GetOwinContext();
owinContext.Authentication.User = principal;

目前我找到了解决方法。如果有人找到更好的东西,我很乐意听到。

在我的DelegatingHandler中,我已经将身份存储在OwinContext环境中:

owinContext.Set<ClaimsIdentity>("customdata:identity", principal);

然后我创建了一个自定义 AuthorizeAttribute,它将当前身份提取出来并分配给当前用户。

IOwinContext context = actionContext.Request.GetOwinContext();
owinContext.Authentication.User = context.Get<ClaimsIdentity>("customdata:identity");
actionContext.RequestContext.Principal = owinContext.Authentication.User;