Asp.net web api OWIN在OData$批处理请求上丢失标识

Asp.net web api OWIN在OData$批处理请求上丢失标识,asp.net-web-api,odata,owin,owin-middleware,Asp.net Web Api,Odata,Owin,Owin Middleware,我正试图将我的标准WebApi应用程序移到OWIN,但身份和$batch请求有问题 我目前有一个DelegatingHandler,它在SendAsync中检测并分配标识: // Detect bearer token and build the identity above. IOwinContext owinContext = request.GetOwinContext(); owinContext.Authentication.User = new ClaimsPrincipal(ide

我正试图将我的标准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
请求时,属性返回到未经验证的
ClaimSideEntity

即使是
GetOwinContext
也会在没有任何用户的情况下返回
IOwinContext
。我假设它已经为每个批处理部件创建了一个新的上下文,但是我看不到任何找到原始上下文的方法


任何帮助都会很好

在您的
SendAsync
方法中,请尝试:

request.GetRequestContext().Principal = new ClaimsPrincipal(identity);
这将同时分配
Thread.CurrentPrincipal
和当前OWIN上下文(选中此项)。 我不是100%确定,但我猜测当前线程中没有设置主体,因为OData在不同线程中执行$batch sub请求,并且OWIN上下文丢失

另一个选项是在
配置
方法中从OWIN中间件分配标识,而不是在
DelegatingHandler
中进行分配。这在回答中得到了解释:,这在某种程度上也与你的问题有关


希望能有帮助

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

在您的
DelegatingHandler
中尝试此操作

var-principal=new-ClaimsPrincipal(标识);
System.Threading.Thread.CurrentPrincipal=主体;
if(System.Web.HttpContext.Current!=null){
System.Web.HttpContext.Current.User=主体;
}
//检测承载令牌并构建上面的标识。
IOwinContext owinContext=request.GetOwinContext();
owinContext.Authentication.User=主体;

目前我找到了一个解决方法。如果有人找到更好的,我很想听

在我的
DelegatingHandler
中,我已将标识存储在OwinContext环境中:

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

您是否在使用
.ConfigureAwait(false)
带有
await'的任何位置?这将导致在恢复执行时不重用http上下文。另外,当调用者发出
batch`请求时,查看实际发送到服务器的内容(如http头)也很有趣,可能是客户端实现(如果未发送承载令牌)而不是服务器上的错误。关于此代码或相关代码,您还有其他见解吗?没有。我没有在任何地方使用
。ConfigureAwait(false)
。恐怕两者都不起作用:(我以前尝试过第一种方法。
app.Use((context,func)
只对批处理请求调用,而不对子请求调用,因此标识仍然丢失。但是您说您在
DelegatingHandler
中拥有
标识,对吗?那么,好吧,忘记OWIN Middleware,因为它只对批处理请求调用,而不对子请求调用,并且在
DelegatingHa中调用ndler
,设置
request.GetRequestContext().Principal=new-ClaimsPrincipal(identity);
,正如我在回答中第一次说的那样。这不起作用很奇怪:(我将在几个小时后再次尝试编辑我的答案。对于$batch request,会调用委派处理程序,对于WebApi的每个子请求,会再次调用委派处理程序。然而,OWIN似乎会为每个子请求创建一个新线程,这不是标准WebApi所做的。以前,他们会对子用户产生影响,但我必须将身份加载到OWIN环境,并在稍后将其拉回来作为解决方法。
IOwinContext context = actionContext.Request.GetOwinContext();
owinContext.Authentication.User = context.Get<ClaimsIdentity>("customdata:identity");
actionContext.RequestContext.Principal = owinContext.Authentication.User;