Home All Groups Group Topic Archive Search About

Single Sign On using NTLM

Author
19 Jan 2009 6:36 PM
Stefan L
Hi to all,

we have a proprietary client and server application (client and server
both written in C# for .NET 2.0) that is using a TCP/IP-Connection for
communication with a custom protocol.

We now have the need to integrate single-sign-on functionality to our
application, that is:
The client should automatically log on to the server using the currently
logged-in windows user without showing any password dialogs.

After a pretty long time of investigation now I only found the Windows
SSPI-framework that is able to do the job, but it requires writing
dozens of pages of code involving unsafe Win32-API.

As I thought that this is kind of a basic functionality (like in IIS,
just checking the "use integrated security"-box...) I am hoping that
somebody can give me a hint on how to perform the necessary steps to
implement the security checks.

So, here are my questions:

- Is there someone who already implemented somthing like this (SSPI)
using .NET?

- Are there any libraries / example code available that can help to do
the job (that is: generate the tokens to exchange between client and
server)?

- Is there an alternative approach here except using the SSPI and NTLM?
As we have to stick with .NET 2.0 here, LDAP-Directories also do not
seem to work any better.


Thanks in advance for all your support!
Stefan

Author
19 Jan 2009 8:37 PM
Joe Kaplan
You can wrap your NetworkStream in a NegotiateStream to get this
functionality.  This will give you NTLM or Kerberos, depending on how your
server is configured.

It is possible to write your own lower level wrappers around the Windows
authentication APIs (InitializeSecurityContext, etc.) to implement Negotiate
authentication, but it is a lot more work.  It is much easier to use
NegotiateStream.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
Show quoteHide quote
"Stefan L" <slueck@pp-software.REMOVEIfNoSpam.de> wrote in message
news:ejGSPTmeJHA.1268@TK2MSFTNGP04.phx.gbl...
> Hi to all,
>
> we have a proprietary client and server application (client and server
> both written in C# for .NET 2.0) that is using a TCP/IP-Connection for
> communication with a custom protocol.
>
> We now have the need to integrate single-sign-on functionality to our
> application, that is:
> The client should automatically log on to the server using the currently
> logged-in windows user without showing any password dialogs.
>
> After a pretty long time of investigation now I only found the Windows
> SSPI-framework that is able to do the job, but it requires writing dozens
> of pages of code involving unsafe Win32-API.
>
> As I thought that this is kind of a basic functionality (like in IIS, just
> checking the "use integrated security"-box...) I am hoping that somebody
> can give me a hint on how to perform the necessary steps to implement the
> security checks.
>
> So, here are my questions:
>
> - Is there someone who already implemented somthing like this (SSPI) using
> .NET?
>
> - Are there any libraries / example code available that can help to do the
> job (that is: generate the tokens to exchange between client and server)?
>
> - Is there an alternative approach here except using the SSPI and NTLM? As
> we have to stick with .NET 2.0 here, LDAP-Directories also do not seem to
> work any better.
>
>
> Thanks in advance for all your support!
> Stefan
Are all your drivers up to date? click for free checkup

Author
20 Jan 2009 8:46 AM
Stefan L
Hello Joe,

even though it does not completly fit into my existing framework (there
are already classes around the NetworkStream that take care of other
protocol issues), it is still pretty much what I was looking for.
I think I'll give it a shot and try to integrate it. It's in any case
much easier to handle than manually implementing the SSPI.

Thanks a lot,
     Stefan


Joe Kaplan schrieb:
Show quoteHide quote
> You can wrap your NetworkStream in a NegotiateStream to get this
> functionality.  This will give you NTLM or Kerberos, depending on how
> your server is configured.
>
> It is possible to write your own lower level wrappers around the Windows
> authentication APIs (InitializeSecurityContext, etc.) to implement
> Negotiate authentication, but it is a lot more work.  It is much easier
> to use NegotiateStream.
>
Author
20 Jan 2009 8:32 PM
Stefan L
Hi again,

thanks for the hint, I got the NegotiateStream basically working but ran
directly in the next problem:

We also run a WebService that is configured for SSO (NTLM per HTTP) and
hosts functionality that needs to be accessed from our proprietary
server in the name of the calling client (ask for private folders, etc.).

Looks like this:
Client --> Server (impersonate) --> IIS-WebServer (AccessDenied)

I found that I need impersonation with permission to delegate, and
here's the problem. NegotiateStream always selects NTLM and eventually
TokenAccessLevel is only Impersonation, not Delegation. That results in
the fact, that the "delegation"-scenario is only working, if the
WebServer and other Server are run on the same machine.

I'm not sure what I have to do to come over this. I guess my problem is,
that I do not have an SPN defined when calling AuthenticateAsClient,
which is needed for Kerberos and delegation.
Documentation seems to be sparse here, I didn't even really find out
what an SPN is. I tried all kinds of things for SPN here, like
specifying the account name "<domain>\<serviceaccountname>" or something
like "HOST/<ServerName>". Nothing.

- Is there any good documentation available on using (creating?) SPNs
(for users of .NET 2.0)?
- Is it really the missing/wrong SPN causing the trouble here?
- How likely is it that I did all right and the PDC is not configured
correctly (Our netwerk clerk was not that much of a help here...)?

I know my questions are hard to answer, but I would really appreciate if
anyone could help me here...

TIA,
    Stefan



Joe Kaplan schrieb:
Show quoteHide quote
> You can wrap your NetworkStream in a NegotiateStream to get this
> functionality.  This will give you NTLM or Kerberos, depending on how
> your server is configured.
>
> It is possible to write your own lower level wrappers around the Windows
> authentication APIs (InitializeSecurityContext, etc.) to implement
> Negotiate authentication, but it is a lot more work.  It is much easier
> to use NegotiateStream.
>
Author
21 Jan 2009 2:30 PM
Joe Kaplan
You should be able to Kerb auth from your client to your server by
specifying an SPN on the service account that runs the service and then
specifying that SPN in your target parameter for your NegotiateStream.
However, you may not need to.

It may be much easier to implement protocol transition logon at the server
service and then using constrained delegation to the IIS web service.  This
type of solution is frequently used in cases where it is difficult or
impossible to guarantee Kerberos login at the front end of your application
but you still need to delegate.

Getting this working can be a bit of a pain and will likely require that you
read up on the TechNet docs on implementing constrained delegation and
protocol transition.  Here are some high level requirements:

- You must have a 2003 Forest Function Level AD or higher to use protocol
transition.  No 2000 AD forests or 2003 mixed mode.
- Protocol transition logon also requires constrained delegation as it
cannot be used in unconstrained mode
- Servers participating must be 2003 or higher
- You must have working Kerberos authentication to the backend (IIS web
service in your case)

The way I usually approach this is to ensure I've got Kerb auth to the
backend verifying that the SPN for the DNS name of the service is properly
set on the service account running the service.  I use the wfetch tool from
the IIS6 res kit for testing Kerb auth as it bypasses some of the weirdness
you'll sometimes see with IE as a Kerb client.

Then, I configure the delegation settings on the front end service account
(trusted for delegation "with any protocol" and configured to delegate to
the SPN of the backend service).  Then I try to see if I can get it to work.
Usually the security event log on the backend server is the most useful tool
to verify the type of authentication being performed.  If you see the NTLM
SSP being used to log in the anonymous account, delegation is not working.
:)

Best of luck getting this sorted.  These types of architectures are totally
possible to build in Windows, but they can be a real pain to get working.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
Show quoteHide quote
"Stefan L" <slueck@pp-software.REMOVEIfNoSpam.de> wrote in message
news:uaZdH5zeJHA.1272@TK2MSFTNGP04.phx.gbl...
> Hi again,
>
> thanks for the hint, I got the NegotiateStream basically working but ran
> directly in the next problem:
>
> We also run a WebService that is configured for SSO (NTLM per HTTP) and
> hosts functionality that needs to be accessed from our proprietary server
> in the name of the calling client (ask for private folders, etc.).
>
> Looks like this:
> Client --> Server (impersonate) --> IIS-WebServer (AccessDenied)
>
> I found that I need impersonation with permission to delegate, and here's
> the problem. NegotiateStream always selects NTLM and eventually
> TokenAccessLevel is only Impersonation, not Delegation. That results in
> the fact, that the "delegation"-scenario is only working, if the WebServer
> and other Server are run on the same machine.
>
> I'm not sure what I have to do to come over this. I guess my problem is,
> that I do not have an SPN defined when calling AuthenticateAsClient, which
> is needed for Kerberos and delegation.
> Documentation seems to be sparse here, I didn't even really find out what
> an SPN is. I tried all kinds of things for SPN here, like specifying the
> account name "<domain>\<serviceaccountname>" or something like
> "HOST/<ServerName>". Nothing.
>
> - Is there any good documentation available on using (creating?) SPNs (for
> users of .NET 2.0)?
> - Is it really the missing/wrong SPN causing the trouble here?
> - How likely is it that I did all right and the PDC is not configured
> correctly (Our netwerk clerk was not that much of a help here...)?
>
> I know my questions are hard to answer, but I would really appreciate if
> anyone could help me here...
>
> TIA,
>    Stefan
>
>
>
> Joe Kaplan schrieb:
>> You can wrap your NetworkStream in a NegotiateStream to get this
>> functionality.  This will give you NTLM or Kerberos, depending on how
>> your server is configured.
>>
>> It is possible to write your own lower level wrappers around the Windows
>> authentication APIs (InitializeSecurityContext, etc.) to implement
>> Negotiate authentication, but it is a lot more work.  It is much easier
>> to use NegotiateStream.
>>
Author
29 Jan 2009 9:03 PM
Stefan L
Hmmm...

OK, I have to admit that I gave up here, I didn't get it working.

We finally decided to modify the web server (thank god we had the
source!) to support a special service account that is able to switch
users as it needs to. This was much easier than implementing the setup
Joe described. Even though not so fancy as the impersonation scenario,
I'm really grateful we were able to find a "boring" alternative.

After all, I still thank you Joe for being so patient to answer my
questions here!!

Best regards and all the best for everybody implementing something
involving SSPI,
     Stefan



Joe Kaplan schrieb:
Show quoteHide quote
> You should be able to Kerb auth from your client to your server by
> specifying an SPN on the service account that runs the service and then
> specifying that SPN in your target parameter for your NegotiateStream.
> However, you may not need to.
>
> It may be much easier to implement protocol transition logon at the
> server service and then using constrained delegation to the IIS web
> service.  This type of solution is frequently used in cases where it is
> difficult or impossible to guarantee Kerberos login at the front end of
> your application but you still need to delegate.
>
> Getting this working can be a bit of a pain and will likely require that
> you read up on the TechNet docs on implementing constrained delegation
> and protocol transition.  Here are some high level requirements:
>
> - You must have a 2003 Forest Function Level AD or higher to use
> protocol transition.  No 2000 AD forests or 2003 mixed mode.
> - Protocol transition logon also requires constrained delegation as it
> cannot be used in unconstrained mode
> - Servers participating must be 2003 or higher
> - You must have working Kerberos authentication to the backend (IIS web
> service in your case)
>
> The way I usually approach this is to ensure I've got Kerb auth to the
> backend verifying that the SPN for the DNS name of the service is
> properly set on the service account running the service.  I use the
> wfetch tool from the IIS6 res kit for testing Kerb auth as it bypasses
> some of the weirdness you'll sometimes see with IE as a Kerb client.
>
> Then, I configure the delegation settings on the front end service
> account (trusted for delegation "with any protocol" and configured to
> delegate to the SPN of the backend service).  Then I try to see if I can
> get it to work. Usually the security event log on the backend server is
> the most useful tool to verify the type of authentication being
> performed.  If you see the NTLM SSP being used to log in the anonymous
> account, delegation is not working. :)
>
> Best of luck getting this sorted.  These types of architectures are
> totally possible to build in Windows, but they can be a real pain to get
> working.
>

Bookmark and Share