【发布时间】:2014-01-27 07:30:04
【问题描述】:
我有一个 WCF 服务,它的 Thread.CurrentPrincipal 设置在 ServiceConfiguration.ClaimsAuthorizationManager 中。
当我像这样异步实现服务时:
public IAsyncResult BeginMethod1(AsyncCallback callback, object state)
{
// Audit log call (uses Thread.CurrentPrincipal)
var task = Task<int>.Factory.StartNew(this.WorkerFunction, state);
return task.ContinueWith(res => callback(task));
}
public string EndMethod1(IAsyncResult ar)
{
// Audit log result (uses Thread.CurrentPrincipal)
return ar.AsyncState as string;
}
private int WorkerFunction(object state)
{
// perform work
}
我发现 Thread.CurrentPrincipal 在 Begin-method 和 WorkerFunction 中设置为正确的 ClaimsPrincipal,但在 End-method 中设置为 GenericPrincipal。
我知道我可以为服务启用 ASP.NET 兼容性并使用 HttpContext.Current.User,它在所有方法中都具有正确的主体,但我不想这样做。
有没有办法在不打开 ASP.NET 兼容性的情况下强制 Thread.CurrentPrincipal 使用正确的 ClaimsPrincipal?
【问题讨论】:
-
为什么会有这么复杂的代码?这段代码实际上并不是服务调用的异步实现。你得到一个同步调用,将它包装在一个在线程池线程中运行的任务中(它不保留主体),然后将它转换为旧式 APM 方法对 - 为什么?创建一个适当的异步方法而不是静态 WorkerFunction 并将主体作为参数传递,而不是在某些任意线程的属性中设置它
-
@PanagiotisKanavos:代码确实是异步的,因为它是在 APM 方法上运行的 WCF async pattern 的一部分。此外,一旦设置了主体,它在传递给任务或线程池线程时被保留,因为用户主体存储在CallContext 中。
-
@user18044 哎呀,我在考虑 .NET 4.5,您可以在其中定义一个 Task
Method1Async 来异步实现 Method1。这对客户端如何生成代理和调用您的方法没有影响,只是对服务代码如何实现合同有影响。您可以轻松拨打 client.Method1,电话将转至MethodAsync
标签: wcf async-await wif iprincipal executioncontext