我正在尝试将我的标准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
请求时,该属性将返回未经身份验证的ClaimsIdentity
。
即使GetOwinContext
在没有任何用户的情况下返回IOwinContext
。我假设它为每个批处理部分创建了一个新的上下文,但我看不到找到原始上下文的任何方法。
任何帮助都会很棒!
答案 0 :(得分:1)
在SendAsync
方法中试试:
request.GetRequestContext().Principal = new ClaimsPrincipal(identity);
这将分配Thread.CurrentPrincipal
和当前的OWIN上下文(请查看此link)。
我不是100%肯定,但我的猜测是Principal没有在当前线程中设置,因为OData在不同的线程中执行$ batch子请求,并且OWIN上下文丢失。
另一种选择是使用Configuration
方法从OWIN中间件中分配标识,而不是在DelegatingHandler
中进行标识。在这个答案中解释了这一点:https://stackoverflow.com/a/21420794/4067893,这也与您的问题有某种关系。
希望它有所帮助。
答案 1 :(得分:1)
目前我找到了一个解决方法。如果有人找到更好的东西,我很乐意听到它。
在我的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;
答案 2 :(得分:0)
批处理的子请求在不同的线程中执行,并且在这些请求中丢失了authenticate主体。
在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;