代码之家  ›  专栏  ›  技术社区  ›  urig

WCF服务的神秘“访问被拒绝”异常

  •  1
  • urig  · 技术社区  · 14 年前

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

    为什么会发生这种情况,我怎样才能找到更多关于这里出了什么问题的信息?

    谢谢, 乌里格

    2 回复  |  直到 14 年前
        1
  •  2
  •   Henk Holterman    14 年前

    从“自定义身份验证”和“[当]几十个客户端同时连接时”,我猜您的自定义身份验证(从堆栈跟踪:授权部分)不是完全线程安全的。授权部分中的任何错误都可能被(错误地)诊断为“拒绝访问”错误。

        2
  •  3
  •   urig    14 年前

    仍然没有解决这个问题,但我确信它确实在我自己的自定义身份验证机制中-所以我接受Henk的答案。

    <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.Diagnostics.TraceEventCache.get\u Callstack() System.Diagnostics.XmlWriterTraceListener.WriteFooter(跟踪事件缓存 事件缓存) System.Diagnostics.TraceSource.TraceData(TraceEventType) System.ServiceModel.Diagnostics.DiagnosticTrace.TraceEvent(TraceEventType) 描述,TraceRecord trace, 异常,对象源) 类型,跟踪代码,字符串 System.IdentityModel.SecurityUtils.CreateDefaultAuthorizationContext(IList)`1 System.ServiceModel.ServiceSecurityContext.get\u AuthorizationContext() 操作上下文)在。。。 操作上下文、消息和;消息)在 >System.ServiceModel.Dispatcher.AuthorizationBehavior.Authorize(MessageRpc& rpc) System.ServiceModel.Dispatcher.MessageRpc.Process(布尔值 等操作上下文集) System.ServiceModel.Dispatcher.ChannelHandler.DispatchedReleasePump(请求上下文 请求,布尔线程, 当前操作上下文) System.ServiceModel.Dispatcher.ChannelHandler.HandlerRequest(请求上下文 请求,操作上下文 System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult) System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke2() 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.scheduledverlapped.IOCallback(UInt32) 错误代码,UInt32个字节, 本机重叠*本机重叠) System.ServiceModel.Diagnostics.Utility.IOCompletionThunk.UnhandledExceptionFrame(UInt32)未处理异常 错误,UInt32 bytesRead, 本机重叠*本机重叠) System.Threading.\u IOCompletionCallback.PerformIOCompletionCallback(UInt32) 错误代码,UInt32个字节, 本地重叠*pOVERLAP)

    Dispatcher.AuthorizationBehavior.Authorize()之后的下一个调用是我自己的AuthorizationManager实现。这很可能就是问题的根源。Authorize()方法仅抛出FaultException作为结果。