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

发布于 2024-09-08 10:55:44 字数 2031 浏览 6 评论 0原文

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

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

谢谢, 乌里格

I have a secure WCF service with custom authentication. When I am stress testing it - having a few dozens of clients connect at the same time, I often get the following exception in my server-side logs:

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)

I've enabled tracing through System.Diagnostics but that only got me a longer stack trace:

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

Why is this happening and how can I find out more about what's going wrong here?

Thanks,
urig

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冷情妓 2024-09-15 10:55:44

仍然没有解决问题,但我确信它确实在我自己的自定义身份验证机制内 - 所以我接受 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
事件缓存)
System.Diagnostics.TraceSource.TraceData(TraceEventType
事件类型、Int32 id、对象数据)
System.ServiceModel.Diagnostics.DiagnosticTrace.TraceEvent(TraceEventType
类型、TraceCode 代码、字符串
描述、TraceRecord 跟踪、
异常异常,对象源)
System.ServiceModel.Diagnostics.DiagnosticTrace.TraceEvent(TraceEventType
类型、TraceCode 代码、字符串
描述)
System.IdentityModel.SecurityUtils.CreateDefaultAuthorizationContext(IList`1
授权政策)
System.ServiceModel.ServiceSecurityContext.get_AuthorizationContext()
Foo.Bar..Core.Security.SessionAuthorizationManager.CheckClaimSet(OperationContext
操作上下文)在...
Foo.Bar..Core.Security.SessionAuthorizationManager.CheckAccess(OperationContext
操作上下文、消息&消息)中
...
<强>> System.ServiceModel.Dispatcher.AuthorizationBehavior.Authorize(MessageRpc&
RPC)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc&
远程过程调用)
System.ServiceModel.Dispatcher.MessageRpc.Process(布尔值
isOperationContextSet)
System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(RequestContext
请求,布尔清洁线程,
操作上下文
当前操作上下文)
System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(RequestContext
请求、操作上下文
当前操作上下文)
System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult
结果)
System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke2()
System.Security.SecurityContext.Run(SecurityContext
安全上下文、上下文回调
回调,对象状态)
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
错误代码,UInt32 numBytes,
NativeOverlapped* nativeOverlapped)
System.ServiceModel.Diagnostics.Utility.IOCompletionThunk.UnhandledExceptionFrame(UInt32
错误,UInt32 字节读取,
NativeOverlapped* nativeOverlapped)
System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32
错误代码,UInt32 numBytes,
NativeOverlapped* pOVERLAP)

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

Still haven't fixed the problem but I'm sure it's indeed within my own custom authentication mechanism - so I'm accepting Henk's answer.

For me, the smoking gun was found when I added diagnostics for System.IdentityModel like so:

<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>

and in the resulting traces saw this:

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 code, String
description, TraceRecord trace,
Exception exception, Object source)
System.ServiceModel.Diagnostics.DiagnosticTrace.TraceEvent(TraceEventType
type, TraceCode code, String
description)
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& message) in
...
> 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(UInt32
errorCode, UInt32 numBytes,
NativeOverlapped* pOVERLAP)

The very next call after Dispatcher.AuthorizationBehavior.Authorize() is to my own implementation of AuthorizationManager. That is most probably where the problem comes from. The Authorize() method merely throws the FaultException as a result.

别靠近我心 2024-09-15 10:55:44

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

InnerException 属性中可能有更多信息。但除此之外,也许您可​​以发布您自己的授权代码的一些详细信息。

From "custom authentication" and "[when] a few dozens of clients connect at the same time" I would guess that your custom authentication (from the stack trace: the authorization part) is not fully thread-safe. It could be that any error in the authorization part is (mis-)diagnosed as an "Access denied" error.

There might be some more information in the InnerException properties. But otherwise, maybe you can post some details of your own authorization code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文