gpt4 book ai didi

wcf - Wif 保护 WCF 服务,缓存 token - 异步 wcf 方法丢失身份

转载 作者:行者123 更新时间:2023-12-02 00:33:14 24 4
gpt4 key购买 nike

我有一个使用 WIF 保护的 wcf 服务。我正在客户端(一个网站)上实现 token 缓存,如 Travis Spencer 的博客中所述:

http://travisspencer.com/blog/2009/03/caching-tokens-to-avoid-calls.html

该网站正在使用模拟(模拟我),STS wcf 端点配置为使用 Windows 身份验证。

当使用直接调用(即非异步调用)调用 WCF 服务时, token 缓存工作正常 - ClientCredentials 行为被删除并添加了我的自定义 CacheClientCredentials 行为, token 在第一次调用时缓存并在后续调用中重用称呼。

但是我有一个场景,其中在 wcf 服务上调用异步方法,并提供回调。在正常情况下(非异步)CacheClientCredentialsSecurityTokenManager.CreateSecurityTokenProvider 方法被多次调用,并且在每次调用时线程运行的身份都是正确的。对 STS 的后续调用使用正确的凭据,用户通过身份验证并返回 token 。调用异步方法时,会多次调用 CacheClientCredentialsSecurityTokenManager.CreateSecurityTokenProvider,但只有第一次调用具有正确的标识。随后的调用将“NT AUTHORITY\NETWORK SERVICE”作为标识。因此,对 STS 的调用具有错误的凭据,并且身份验证失败。 (STS日志显示“无法通过身份验证”的消息。

我一直在尝试围绕 Begin/End 异步方法添加显式模拟,但这并不总是奏效。然后我将以下值添加到 web.config 中:

    <legacyImpersonationPolicy enabled="false" />
<alwaysFlowImpersonationPolicy enabled="true" />

这也不总是有效(尽管有时有效)。这里不寻常的是,业务逻辑涉及 3 次调用异步方法的尝试(如果调用失败)。我发现通常前 2 次失败,第三次成功 - 即 CacheClientCredentialsSecurityTokenManager.CreateSecurityTokenProvider 通常前两次以错误的身份运行,第三次以正确的身份运行 - 但这似乎也有点随机。当 CacheClientCredentialsSecurityTokenManager.CreateSecurityTokenProvider 以正确的身份成功时,WCF 调用就会成功。但是 token 没有添加到缓存中(没有 token 缓存代码被执行)后续调用非异步方法然后构造一个新的缓存然后获取 token ,将其添加到缓存中。

调用使用 WIF 保护的异步 WCF 方法以确保跨调用缓存 WIF token 的正确方法是什么?

是否需要特殊的身份配置来确保在所有这些流程中使用相同的身份? (所有区域都在使用模拟)

更新:

我不确定它是否增加了很多,但我发现当代码不起作用时,以下是 CacheClientCredentialsSecurityTokenManager 中的堆栈跟踪:

Unflagged   >   5732    18  Worker Thread   <No Name>   CacheClientCredentialsSecurityTokenManager.CreateSecurityTokenProvider  Normal
MySecurity.dll!CacheClientCredentialsSecurityTokenManager.CreateSecurityTokenProvider(System.IdentityModel.Selectors.SecurityTokenRequirement tokenRequirement) Line 18
System.ServiceModel.dll!System.ServiceModel.Security.SecurityProtocol.AddSupportingTokenProviders(System.ServiceModel.Security.Tokens.SupportingTokenParameters supportingTokenParameters, bool isOptional, System.Collections.Generic.IList<System.ServiceModel.Security.SupportingTokenProviderSpecification> providerSpecList) + 0xca bytes
System.ServiceModel.dll!System.ServiceModel.Security.SecurityProtocol.OnOpen(System.TimeSpan timeout) + 0xa7 bytes
System.ServiceModel.dll!System.ServiceModel.Security.SymmetricSecurityProtocol.OnOpen(System.TimeSpan timeout) + 0x45 bytes
System.ServiceModel.dll!System.ServiceModel.Security.OperationWithTimeoutAsyncResult.OnScheduled(object state) + 0x82 bytes
System.ServiceModel.dll!System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke2() + 0x46 bytes
System.ServiceModel.dll!System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.OnSecurityContextCallback(object o) + 0x28 bytes
mscorlib.dll!System.Security.SecurityContext.Run(System.Security.SecurityContext securityContext, System.Threading.ContextCallback callback, object state) + 0x55 bytes
System.ServiceModel.dll!System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke() + 0x4d bytes
System.ServiceModel.dll!System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ProcessCallbacks() + 0x180 bytes
System.ServiceModel.dll!System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.CompletionCallback(object state) + 0x7a bytes
System.ServiceModel.dll!System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ScheduledOverlapped.IOCallback(uint errorCode, uint numBytes, System.Threading.NativeOverlapped* nativeOverlapped) + 0xf bytes
SMDiagnostics.dll!System.ServiceModel.Diagnostics.Utility.IOCompletionThunk.UnhandledExceptionFrame(uint error, uint bytesRead, System.Threading.NativeOverlapped* nativeOverlapped) + 0x3d bytes
mscorlib.dll!System.Threading._IOCompletionCallback.PerformIOCompletionCallback(uint errorCode, uint numBytes, System.Threading.NativeOverlapped* pOVERLAP) + 0x54 bytes
[Appdomain Transition]

当它工作时,它有点不同(注意额外的 mscorlib 条目和中间的转换):

Unflagged   >   5408    12  Worker Thread   <No Name>   CacheClientCredentialsSecurityTokenManager.CreateSecurityTokenProvider  Normal
MySecurity.dll!CacheClientCredentialsSecurityTokenManager.CreateSecurityTokenProvider(System.IdentityModel.Selectors.SecurityTokenRequirement tokenRequirement) Line 18
System.ServiceModel.dll!System.ServiceModel.Security.SecurityProtocol.AddSupportingTokenProviders(System.ServiceModel.Security.Tokens.SupportingTokenParameters supportingTokenParameters, bool isOptional, System.Collections.Generic.IList<System.ServiceModel.Security.SupportingTokenProviderSpecification> providerSpecList) + 0xca bytes
System.ServiceModel.dll!System.ServiceModel.Security.SecurityProtocol.OnOpen(System.TimeSpan timeout) + 0xa7 bytes
System.ServiceModel.dll!System.ServiceModel.Security.SymmetricSecurityProtocol.OnOpen(System.TimeSpan timeout) + 0x45 bytes
System.ServiceModel.dll!System.ServiceModel.Security.OperationWithTimeoutAsyncResult.OnScheduled(object state) + 0x82 bytes
System.ServiceModel.dll!System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke2() + 0x46 bytes
System.ServiceModel.dll!System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.OnSecurityContextCallback(object o) + 0x28 bytes
***mscorlib.dll!System.Security.SecurityContext.runTryCode(object userData) + 0x6e bytes
[Native to Managed Transition]
[Managed to Native Transition]
***mscorlib.dll!System.Security.SecurityContext.RunInternal(System.Security.SecurityContext securityContext, System.Threading.ContextCallback callBack, object state) + 0xc2 bytes
***mscorlib.dll!System.Security.SecurityContext.Run(System.Security.SecurityContext securityContext, System.Threading.ContextCallback callback, object state) + 0xca bytes
System.ServiceModel.dll!System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke() + 0x4d bytes
System.ServiceModel.dll!System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ProcessCallbacks() + 0x180 bytes
System.ServiceModel.dll!System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.CompletionCallback(object state) + 0x7a bytes
System.ServiceModel.dll!System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ScheduledOverlapped.IOCallback(uint errorCode, uint numBytes, System.Threading.NativeOverlapped* nativeOverlapped) + 0xf bytes
SMDiagnostics.dll!System.ServiceModel.Diagnostics.Utility.IOCompletionThunk.UnhandledExceptionFrame(uint error, uint bytesRead, System.Threading.NativeOverlapped* nativeOverlapped) + 0x3d bytes
mscorlib.dll!System.Threading._IOCompletionCallback.PerformIOCompletionCallback(uint errorCode, uint numBytes, System.Threading.NativeOverlapped* pOVERLAP) + 0x54 bytes
[Appdomain Transition]

最佳答案

在尝试调用异步方法之前,我没有在代理上显式调用 .Open(),因此 .Open() 似乎发生了在客户端代理内部,在另一个线程上 - 因此存在身份问题。我发现如果我打电话:

If _proxy.State <> CommunicationState.Opened Then
_proxy.Open()
End If

_proxy.Begin[asyncMethod]()

缓存凭证设置和 token 缓存检查同步发生,因此使用正确的身份,并按预期运行。

关于wcf - Wif 保护 WCF 服务,缓存 token - 异步 wcf 方法丢失身份,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5812469/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com