Exception when use asp.net with .net remoting

D

dragooon

Could anyone shed some light on this? We have an asp.net 2.0 application
that works together with .net remoting. The asp.net application calls a .net
remoting server through tcp channel from a separate thread. The basic
workflow is like the following:

Internet user send a request
-> asp.net application creates a new thread
-> the thread then calls .net remoting server to retrieve some
data

This works fine if the IIS server and the .net remoting server are loated on
the same machine (or different machine but we do not run it through the new
created thread). However, when the IIS and the .net remoting server are
located on two different machines, this throws an exception:

System.Security.Authentication.InvalidCredentialException: The server has
rejected the client credentials. ---> System.ComponentModel.Win32Exception:
The logon attempt failed\r\n --- End of inner exception stack
trace ---\r\n\r\nServer stack trace: \r\n at
System.Net.Security.NegoState.ProcessAuthentication(LazyAsyncResult
lazyResult)\r\n at
System.Net.Security.NegotiateStream.AuthenticateAsClient(NetworkCredential
credential, String targetName, ProtectionLevel requiredProtectionLevel,
TokenImpersonationLevel allowedImpersonationLevel)\r\n at
System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.CreateAuthenticatedStream(Stream
netStream, String machinePortAndSid)\r\n at
System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.CreateSocketHandler(Socket
socket, SocketCache socketCache, String machinePortAndSid)\r\n at
System.Runtime.Remoting.Channels.SocketCache.CreateSocketHandler(Socket
socket, String machineAndPort)\r\n at
System.Runtime.Remoting.Channels.RemoteConnection.CreateNewSo
cket(EndPoint ipEndPoint)\r\n at
System.Runtime.Remoting.Channels.RemoteConnection.CreateNewSocket()\r\n at
System.Runtime.Remoting.Channels.SocketCache.GetSocket(String
machinePortAndSid, Boolean openNew)\r\n at
System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.SendRequestWithRetry(IMessage
msg, ITransportHeaders requestHeaders, Stream requestStream)\r\n at
System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.ProcessMessage(IMessage
msg, ITransportHeaders requestHeaders, Stream requestStream,
ITransportHeaders& responseHeaders, Stream& responseStream)\r\n at
System.Runtime.Remoting.Channels.BinaryClientFormatterSink.SyncProcessMessage(IMessage
msg)\r\n\r\nException rethrown at [0]: \r\n at
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage
reqMsg, IMessage retMsg)\r\n at
System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&
msgData, Int32 type)\r\n

Does this an internal problem from .net framework? Any help will be
appreciated!
 
S

Steven Cheng[MSFT]

Hello dragooon,

From your description, you have an ASP.NET web application which will call
a .net remoting object on another remote machine(through TCP channel).
However, you found that the remoting call will result to an exception when
the remotign call code run in a separate thread in ASP.NET(and remoting
server is on remote machine). And it works well if the ASP.NET app and
remoting server are on the same machine or if you're using a separate
thread to accesss the remote object, correct?

As the exception callstack indicate that the exception is raised during the
authentication between remoting client and server, based on my experience,
this is likely a security context issue. In addition to the symtom you
said, I'd like to also confirm the following things:

1. Whether your ASP.NET server machine is 2000/xp or 2003(or whether it is
hosted in IIS5 or IIS6), this will determine whether the ASP.NET process
identity is local account(MACHINE\ASPNET) or NetworkService.

2. Have you used impersonation in your web application or manually change
the ASP.NET process identity to another account.


3. Have you enabled secruity for the remoting TCP channel(this feature is
new in .net remoting 2.0).

My analysis is that your remoting application has enabled security so that
the remoting server will always authenticate the client request. And for
the two working scenarios you mentioned:

* when ASP.NET app and remoting server are on the same machine. No matter
the ASP.NET context thread(or new created separate thread) running under
local accont(or a domain account), the remoting server can correctly
authenticate/recognize it. So no problem here

*when ASP.NET app and remoting server are on different machine, of course,
any local account can not be authenticated by remote server. Here if your
ASP.NET is impersonating under a fixed domain account (through <identity
impersonate userName=xxx password=xxx/> ), then remoting call in main
ASP.NET thread can still pass the authentication. However, if you do it in
a separate thread, (since new thread won't inherit the impersonated
identity, but use the process's identity), if the process's identity is a
local account, the authentication will still fail either.

BTW, at remoting client(in asp.net code), you can use the following
statement to check the current windows security context(in the main thread
or separate thread):

string identity = System.Security.Principal.WindowsIdentity.GetCurrent();

Please have a look at the above items to see whether your scenario fits any
of them. If there is anything I missed, please feel free to let me know.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead



==================================================

Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.



Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.

==================================================



This posting is provided "AS IS" with no warranties, and confers no rights.
 
D

dragooon

Hi Steven -

It looks like a security issue. As you suggested I tried impersonating the
thread and it is working fine now. Thanks for your help on this!

A side note: I tried to use ExecutionContext to fix this issue but it failed
too (used the following call). It is a bit odd why the impersonating will
work and using the same security contect will fail, just curious...
ExecutionContext _ExecutionContext =
ExecutionContext.Capture().CreateCopy();

ExecutionContext.Run(_ExecutionContext, somefunction, null);

Thanks again for your help!

Jesse
 
S

Steven Cheng[MSFT]

Thanks for your reply Jesse,

Glad that it helps. For the ExecutionContext, my understanding is it can
help capture and copy some managed thread info, such as data in thread
context or CAS status. However, for WindowsIdentity, it is still tightly
coupled with operating system, and copy such secuirty context require
impersonation, ExecutionContext.Run won't help call impersonation
internally. In addition, for managed thread principile/identity such as
"Thread.CurrentPrincipal", it can be copied between managed thread since it
is pure managed object which won't rely on operating system's thread.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead



This posting is provided "AS IS" with no warranties, and confers no rights.
 
D

Dominick Baier

Impersonation tokens, T.CP and othe thread related data *are* propagated
when starting a new thread - this was introduced in .NET 2.0

That said - running inside ASP.NET things are different - to stay compatible
with 1.1 async code - this behavior is disabled by default in asp.net - you
can however change this by modifying a file called aspnet.config - read more
here:

http://www.leastprivilege.com/WhatIsAspnetconfig.aspx
 
B

Brian

Hi Dominick,

I tried adding the following code to web.config but it did not fix the
problem (in my case I was executing SQL access and printing from a new
asp.net Thread):

<runtime>
<legacyUnhandledExceptionPolicy enabled="false" />

<SymbolReadingPolicy enabled="1" />

<legacyImpersonationPolicy enabled="false" />

<alwaysFlowImpersonationPolicy enabled="true" />

</runtime>

In the end I added the following line to the new thread and this fixed the
problem:

((WindowsIdentity)Thread.CurrentPrincipal.Identity).Impersonate();

Is there something I am doing wrong with the Web.Config options?

Brian
 
D

Dominick Baier

The configuration does *not* go to web.config - as my blog article described
- you have to modify aspnet.config.
 
B

Brian

Hi Dominick,

Thanks very much pointing that out - sorry for missing that.

And yes it worked!

(Now there is another problem printing from ASP.Net - I plan to post this as
a new item on this newsgroup.

Thanks again,
Brian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top