WCF服务的隐秘“访问被拒绝”例外

时间:2010-07-04 08:55:37

标签: wcf wcf-security

我有一个带有自定义身份验证的安全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

2 个答案:

答案 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属性中可能还有更多信息。但是,否则,您可以发布自己授权代码的一些细节。