Authentication Using SSPI

When authenticating against Active Directory, we can use a couple of techniques in order to validate a user's credentials using native Windows protocols rather than LDAP. One valid technique is to use the LogonUser API. This technique is fairly well understood, and resources like www.pinvoke.net have ready-made code snippets that demonstrate how to use the API successfully. We won't cover this technique, other than to say that for Windows 2000, this technique has some fairly significant limitations. This topic and more are covered in detail in The .NET Developer's Guide to Windows Security. While these limitations have been removed with subsequent Windows releases, we feel that an easier technique is available that addresses all NT-based versions of Windows.

SSPI authentication has become much easier with .NET 2.0, and it is a handy way to sidestep any security issues that crop up with LogonUser. While this technique really is not LDAP or ADSI related in any sense, it is certainly useful enough to merit coverage. Essentially, we will use the new NegotiateStream class in .NET 2.0 to harness the Negotiate protocol directly. The trick here is to execute a trusted handshake, acting as both the client and the server. Listing 12.6 shows a sample of how this might work.

Listing 12.6. Windows Authentication Using SSPI

using System;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Principal;
using System.Threading;

class NTAuth
{
 TcpListener listener;
 int port;

 public NTAuth(int port)
 {
 this.port = port;
 this.listener = new TcpListener(
 IPAddress.Loopback, this.port);
 this.listener.Start();
 }

 private void CreateServer(object state)
 {
 try
 {
 NegotiateStream nsServer = new NegotiateStream(
 this.listener.AcceptTcpClient().GetStream()
 );

 nsServer.AuthenticateAsServer(
 CredentialCache.DefaultNetworkCredentials,
 ProtectionLevel.None,
 TokenImpersonationLevel.Impersonation
 );
 }
 catch (AuthenticationException) {}
 }

 public bool Authenticate(NetworkCredential creds)
 {
 TcpClient client = new TcpClient(
 "localhost",
 this.port
 );

 ThreadPool.QueueUserWorkItem(
 new WaitCallback(CreateServer)
 );

 NegotiateStream nsClient = new NegotiateStream(
 client.GetStream(),
 true
 );

 using (nsClient)
 {
 try
 {
 nsClient.AuthenticateAsClient(
 creds,
 creds.Domain + @"" + creds.UserName,
 ProtectionLevel.None,
 TokenImpersonationLevel.Impersonation
 );
 return nsClient.IsAuthenticated;
 }
 catch (AuthenticationException)
 {
 return false;
 }
 }
 }
}

The SSPI authentication technique will not work with ADAM security principals. As such, this technique applies only to Active Directory installations.

Part I: Fundamentals

Introduction to LDAP and Active Directory

Introduction to .NET Directory Services Programming

Binding and CRUD Operations with DirectoryEntry

Searching with the DirectorySearcher

Advanced LDAP Searches

Reading and Writing LDAP Attributes

Active Directory and ADAM Schema

Security in Directory Services Programming

Introduction to the ActiveDirectory Namespace

Part II: Practical Applications

User Management

Group Management

Authentication

Part III: Appendixes

Appendix A. Three Approaches to COM Interop with ADSI

Appendix B. LDAP Tools for Programmers

Appendix C. Troubleshooting and Help

Index



The. NET Developer's Guide to Directory Services Programming
The .NET Developers Guide to Directory Services Programming
ISBN: 0321350170
EAN: 2147483647
Year: 2004
Pages: 165

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net