我有一个带有自定义身份验证的安全WCF服务。当我对它进行压力测试时 - 有几十个客户端同时连接,我经常在服务器端日志中遇到以下异常:
System.ServiceModel.FaultException: Access is denied.
at System.ServiceModel.Dispatcher.AuthorizationBehavior.Authorize(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
我已经通过System.Diagnostics启用了跟踪,但这只能让我获得更长的堆栈跟踪:
System.ServiceModel.Dispatcher.AuthorizationBehavior.Authorize(MessageRpc& rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)
System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(RequestContext request, Boolean cleanThread, OperationContext currentOperationContext)
System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(RequestContext request, OperationContext currentOperationContext)
System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result)
System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke2()
System.Security.SecurityContext.Run(SecurityContext securityContext, ContextCallback callback, Object state)
System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke()
System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ProcessCallbacks()
System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.CompletionCallback(Object state)
System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
System.ServiceModel.Diagnostics.Utility.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
System.Threading._IOCompletionCallback.PerformIOCompletionCallback
为什么会发生这种情况?如何才能找到更多关于此处出现问题的信息?
谢谢, urig
答案 0 :(得分:3)
仍然没有解决问题,但我确定它确实在我自己的自定义身份验证机制中 - 所以我接受了Henk的回答。
对我来说,当我为System.IdentityModel添加诊断时,就发现了冒烟枪:
<system.diagnostics>
<sources>
<source name="System.IdentityModel" switchValue="All">
<listeners>
<add type="System.Diagnostics.DefaultTraceListener" name="Default">
<filter type="" />
</add>
<add name="IdentityModelListener">
<filter type="" />
</add>
</listeners>
</source>
</sources>
<sharedListeners>
<add initializeData="C:\Tracing\App_identitymodellog.svclog" type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
name="IdentityModelListener" traceOutputOptions="Timestamp, Callstack">
<filter type="" />
</add>
</sharedListeners>
<trace autoflush="true" />
</system.diagnostics>
在最终的痕迹中看到了这个:
System.Environment.get_StackTrace() System.Diagnostics.TraceEventCache.get_Callstack() System.Diagnostics.XmlWriterTraceListener.WriteFooter(TraceEventCache eventCache) System.Diagnostics.TraceSource.TraceData(TraceEventType eventType,Int32 id,Object data) System.ServiceModel.Diagnostics.DiagnosticTrace.TraceEvent(TraceEventType type,TraceCode代码,String 描述,TraceRecord跟踪, 异常异常,对象源) System.ServiceModel.Diagnostics.DiagnosticTrace.TraceEvent(TraceEventType type,TraceCode代码,String 描述) System.IdentityModel.SecurityUtils.CreateDefaultAuthorizationContext(IList`1 authorizationPolicies) System.ServiceModel.ServiceSecurityContext.get_AuthorizationContext() Foo.Bar..Core.Security.SessionAuthorizationManager.CheckClaimSet(的OperationContext operationContext)in ... Foo.Bar..Core.Security.SessionAuthorizationManager.CheckAccess(的OperationContext operationContext,Message&amp;消息) ... 的&GT; System.ServiceModel.Dispatcher.AuthorizationBehavior.Authorize(MessageRpc&安培; RPC)强> System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc&安培; RPC) System.ServiceModel.Dispatcher.MessageRpc.Process(布尔 isOperationContextSet) System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(的RequestContext request,Boolean cleanThread, 的OperationContext currentOperationContext) System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(的RequestContext 请求,OperationContext currentOperationContext) System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult的 结果) System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke2() System.Security.SecurityContext.Run(SecurityContext的 securityContext,ContextCallback 回调,对象状态) System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke() System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ProcessCallbacks() System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.CompletionCallback(对象 州) System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ScheduledOverlapped.IOCallback(UInt32的 errorCode,UInt32 numBytes, NativeOverlapped * nativeOverlapped) System.ServiceModel.Diagnostics.Utility.IOCompletionThunk.UnhandledExceptionFrame(UInt32的 错误,UInt32 bytesRead, NativeOverlapped * nativeOverlapped) System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32的 errorCode,UInt32 numBytes, NativeOverlapped * pOVERLAP)
Dispatcher.AuthorizationBehavior.Authorize()之后的下一个调用是我自己的AuthorizationManager实现。这很可能是问题的来源。 Authorize()方法仅仅抛出FaultException。
答案 1 :(得分:2)
从“自定义身份验证”和“[当]几十个客户端同时连接”时,我猜你的自定义身份验证(来自堆栈跟踪:授权部分)不是完全线程安全的。可能是授权部分中的任何错误被(错误地)诊断为“拒绝访问”错误。
InnerException属性中可能还有更多信息。但是,否则,您可以发布自己授权代码的一些细节。