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;
我正在尝试将我的标准 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;