Exportieren (0) Drucken
Alle erweitern

NegotiateStream-Klasse

Hinweis: Diese Klasse ist neu in .NET Framework, Version 2.0.

Stellt einen Stream bereit, der mit dem Sicherheitsprotokoll Negotiate den Client und optional den Server für die Kommunikation zwischen Client und Server authentifiziert.

Namespace: System.Net.Security
Assembly: System (in system.dll)

public class NegotiateStream : AuthenticatedStream
public class NegotiateStream extends AuthenticatedStream
public class NegotiateStream extends AuthenticatedStream

Die NegotiateStream-Klasse dient der Authentifizierung sowie der Sicherung der zwischen einem Client und einem Server übermittelten Informationen. Mit NegotiateStream kann Folgendes ausgeführt werden:

  • Senden von Clientanmeldeinformationen an den Server für einen Identitätswechsel oder eine Delegierung.

  • Anfordern der Serverauthentifizierung.

  • Verschlüsseln und/oder Signieren von Daten vor dem Übertragen.

Die Authentifizierung muss vor dem Übertragen von Informationen ausgeführt werden. Clients fordern Authentifizierungen mithilfe von synchronen AuthenticateAsClient-Methoden an, die bis zum Beenden der Authentifizierung blockiert werden, oder sie verwenden die asynchronen BeginAuthenticateAsClient-Methoden, die während des Authentifizierungsvorgangs nicht blockiert werden. Server fordern Authentifizierungen mit den synchronen AuthenticateAsServer-Methoden oder mit den asynchronen BeginAuthenticateAsServer-Methoden an. Der Client und optional auch der Server werden mit dem Sicherheitsprotokoll Negotiate authentifiziert. Auf Windows 95-/98-Systemen wird das NTLM-Protokoll (Windows NT LAN Manager) zur Authentifizierung verwendet. Auf anderen Plattformen wird das Kerberos-Protokoll zur Authentifizierung verwendet, wenn der Client und der Server dies unterstützen, andernfalls wird NTLM verwendet. Ausführliche Beschreibungen dieser Protokolle finden Sie in der Platform SDK-Dokumentation auf MSDN unter msdn.microsoft.com/library/. Die NegotiateStream-Klasse führt die Authentifizierung unter Verwendung von SSPI (Security Support Provider Interface) aus.

Bei erfolgreicher Authentifizierung müssen Sie die IsEncrypted-Eigenschaft und die IsSigned-Eigenschaft überprüfen, um die vom NegotiateStream zum Sichern der Daten während der Übertragung verwendeten Sicherheitsdienste zu bestimmen. Überprüfen Sie die IsMutuallyAuthenticated-Eigenschaft, um zu bestimmen, ob die gegenseitige Authentifizierung erfolgt ist. Mit der RemoteIdentity-Eigenschaft können Informationen zum Remoteclient oder -server abgerufen werden.

Bei einem Authentifizierungsfehler erhalten Sie eine AuthenticationException oder eine InvalidCredentialException. Sie können die Authentifizierung dann mit anderen Anmeldeinformationen wiederholen.

Das Senden von Daten erfolgt entweder mit den synchronen Write-Methoden oder mit den asynchronen BeginWrite-Methoden. Das Empfangen von Daten erfolgt entweder mit den synchronen Read-Methoden oder mit den asynchronen BeginRead-Methoden. Wenn Sicherheitsdienste, z. B. Verschlüsselung oder Signierung, aktiviert sind, werden diese automatisch vom NegotiateStream auf die Daten angewendet.

Der NegotiateStream überträgt Daten mit einem Stream, den Sie beim Erstellen von NegotiateStream bereitstellen. Beim Bereitstellen des zugrunde liegenden Streams können Sie angeben, ob durch das Schließen des NegotiateStream auch der zugrunde liegende Stream geschlossen wird.

Im folgenden Codebeispiel wird die Clientseite einer Client-Server-Verbindung veranschaulicht, die den NegotiateStream verwendet. Der Client authentifiziert und sendet eine Meldung asynchron an den Server.

using System;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Text;

namespace Examples.NegotiateStreamExample
{
    public class ASynchronousAuthenticatingTcpClient 
    {   
        static TcpClient client = null;

        public static void Main(String[] args)  
        {
            // Establish the remote endpoint for the socket.
            // For this example, use the local machine.
            IPHostEntry ipHostInfo = Dns.GetHostEntry("localhost");
            IPAddress ipAddress = ipHostInfo.AddressList[0];
            // Client and server use port 11000. 
            IPEndPoint remoteEP = new IPEndPoint(ipAddress, 11000);
            // Create a TCP/IP socket.
            client = new TcpClient();
            // Connect the socket to the remote endpoint.
            client.Connect(remoteEP);
            Console.WriteLine("Client connected to {0}.", remoteEP.ToString());
            // Ensure the client does not close when there is 
            // still data to be sent to the server.
            client.LingerState = (new LingerOption(true, 0));
            // Request authentication.
            NetworkStream clientStream = client.GetStream();
            NegotiateStream authStream = new NegotiateStream(clientStream, false); 
            // Pass the NegotiateStream as the AsyncState object 
            // so that it is available to the callback delegate.
            IAsyncResult ar = authStream.BeginAuthenticateAsClient(
                new AsyncCallback(EndAuthenticateCallback),
                authStream
                );
            Console.WriteLine("Client waiting for authentication...");
            // Wait until the result is available.
            ar.AsyncWaitHandle.WaitOne();
            // Display the properties of the authenticated stream.
            AuthenticatedStreamReporter.DisplayProperties(authStream);
            // Send a message to the server.
            // Encode the test data into a byte array.
            byte[] message = Encoding.UTF8.GetBytes("Hello from the client.");
            ar = authStream.BeginWrite(message, 0, message.Length,
                new AsyncCallback(EndWriteCallback),
                authStream);
            ar.AsyncWaitHandle.WaitOne();
            Console.WriteLine("Sent {0} bytes.", message.Length);
            // Close the client connection.
            authStream.Close();
            Console.WriteLine("Client closed.");
        }
        // The following method is called when the authentication completes.
        public static void EndAuthenticateCallback (IAsyncResult ar)
        {
            Console.WriteLine("Client ending authentication...");
            NegotiateStream authStream = (NegotiateStream) ar.AsyncState;

            // End the asynchronous operation.
            authStream.EndAuthenticateAsClient(ar);
//         Console.WriteLine("AllowedImpersonation: {0}", authStream.AllowedImpersonation);
        }
        // The following method is called when the write operation completes.
        public static void EndWriteCallback (IAsyncResult ar)
        {
            Console.WriteLine("Client ending write operation...");
            NegotiateStream authStream = (NegotiateStream) ar.AsyncState;

            // End the asynchronous operation.
            authStream.EndWrite(ar);
        }
    }

    // The following class displays the properties of an authenticatedStream.
    public class AuthenticatedStreamReporter
{
    public static void DisplayProperties(AuthenticatedStream stream)
   {
        Console.WriteLine("IsAuthenticated: {0}", stream.IsAuthenticated);
        Console.WriteLine("IsMutuallyAuthenticated: {0}", stream.IsMutuallyAuthenticated);
        Console.WriteLine("IsEncrypted: {0}", stream.IsEncrypted);
        Console.WriteLine("IsSigned: {0}", stream.IsSigned);
        Console.WriteLine("IsServer: {0}", stream.IsServer);
    }
}
}

Im folgenden Codebeispiel wird die Serverseite einer Client-/Serververbindung veranschaulicht, die mit dem NegotiateStream den Client authentifiziert und eine vom Client gesendete Meldung liest.

using System;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Principal;
using System.Text;
using System.IO;
using System.Threading;

namespace Examples.NegotiateStreamExample
{
    public class AsynchronousAuthenticatingTcpListener 
    {
        public static void Main() 
        {   
            // Create an IPv4 TCP/IP socket. 
            TcpListener listener = new TcpListener(IPAddress.Any, 11000);
            // Listen for incoming connections.
            listener.Start();
            while (true) 
            {
                TcpClient clientRequest = null;
                // Application blocks while waiting for an incoming connection.
                // Type CNTL-C to terminate the server.
                clientRequest = listener.AcceptTcpClient();
                Console.WriteLine("Client connected.");
                // A client has connected. 
                try
                {
                    AuthenticateClient (clientRequest);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    continue;
                }

            }
        
        }
        public static void AuthenticateClient(TcpClient clientRequest)
        {
            NetworkStream stream = clientRequest.GetStream(); 
            // Create the NegotiateStream.
            NegotiateStream authStream = new NegotiateStream(stream, false); 
            // Save the current client and NegotiateStream instance 
            // in a ClientState object.
            ClientState cState = new ClientState(authStream, clientRequest);
            // Listen for the client authentication request.
            authStream.BeginAuthenticateAsServer (
                new AsyncCallback(EndAuthenticateCallback),
                cState
                );
            // Wait until the authentication completes.
            cState.Waiter.WaitOne();
            cState.Waiter.Reset();
            authStream.BeginRead(cState.Buffer, 0, cState.Buffer.Length, 
                   new AsyncCallback(EndReadCallback), 
                   cState);
            cState.Waiter.WaitOne();
            // Finished with the current client.
            authStream.Close();
            clientRequest.Close();
        }
        // The following method is invoked by the
        // BeginAuthenticateAsServer callback delegate.

        public static void EndAuthenticateCallback (IAsyncResult ar)
        {
            // Get the saved data.
            ClientState cState = (ClientState) ar.AsyncState;
            TcpClient clientRequest = cState.Client;
            NegotiateStream authStream = (NegotiateStream) cState.AuthenticatedStream;
            Console.WriteLine("Ending authentication.");
            // Any exceptions that occurred during authentication are
            // thrown by the EndAuthenticateAsServer method.
            try 
            {
                // This call blocks until the authentication is complete.
                authStream.EndAuthenticateAsServer(ar);
            }
            catch (AuthenticationException e)
            {
                Console.WriteLine(e);
                Console.WriteLine("Authentication failed - closing connection.");
                cState.Waiter.Set();
                return;
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                Console.WriteLine("Closing connection.");
                cState.Waiter.Set();
                return;
            }
            // Display properties of the authenticated client.
            IIdentity id = authStream.RemoteIdentity;
            Console.WriteLine("{0} was authenticated using {1}.", 
                id.Name, 
                id.AuthenticationType
                );
            cState.Waiter.Set();

    }
        public static void EndReadCallback(IAsyncResult ar)
        {
            // Get the saved data.
            ClientState cState = (ClientState) ar.AsyncState;
            TcpClient clientRequest = cState.Client;
            NegotiateStream authStream = (NegotiateStream) cState.AuthenticatedStream; 
            // Get the buffer that stores the message sent by the client.
            int bytes = -1;
            // Read the client message.
            try
            {
                    bytes = authStream.EndRead(ar);
                    cState.Message.Append(Encoding.UTF8.GetChars(cState.Buffer, 0, bytes));
                    if (bytes != 0)
                    {
                         authStream.BeginRead(cState.Buffer, 0, cState.Buffer.Length, 
                               new AsyncCallback(EndReadCallback), 
                               cState);
                               return;
                 }
            }
            catch (Exception e)
            {
                // A real application should do something
                // useful here, such as logging the failure.
                Console.WriteLine("Client message exception:");
                Console.WriteLine(e);
                cState.Waiter.Set();
                return;
            }
            IIdentity id = authStream.RemoteIdentity;
            Console.WriteLine("{0} says {1}", id.Name, cState.Message.ToString());
            cState.Waiter.Set();
        }
    }
    // ClientState is the AsyncState object.
    internal class ClientState
    {
        private AuthenticatedStream authStream = null;
        private  TcpClient client = null;
        byte[] buffer = new byte[2048];
        StringBuilder message = null;
        ManualResetEvent waiter = new ManualResetEvent(false);
        internal ClientState(AuthenticatedStream a, TcpClient theClient)
        {
            authStream = a;
            client = theClient;
        }
        internal TcpClient Client
        { 
            get { return client;}
        }
        internal AuthenticatedStream AuthenticatedStream
        {
            get { return authStream;}
        }
        internal byte[] Buffer
        {
              get { return buffer;}
        }
        internal StringBuilder Message
        {
            get 
            { 
                if (message == null)
                    message = new StringBuilder();
                return message;
             }
        }
        internal ManualResetEvent Waiter
        {
            get 
            { 
                return waiter;
             }
        }
    }
}

System.Object
   System.MarshalByRefObject
     System.IO.Stream
       System.Net.Security.AuthenticatedStream
        System.Net.Security.NegotiateStream

Alle öffentlichen statischen (Shared in Visual Basic) Member dieses Typs sind threadsicher. Bei Instanzmembern ist die Threadsicherheit nicht gewährleistet.

Windows 98, Windows 2000 SP4, Windows Millennium Edition, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition

.NET Framework unterstützt nicht alle Versionen sämtlicher Plattformen. Eine Liste der unterstützten Versionen finden Sie unter Systemanforderungen.

.NET Framework

Unterstützt in: 2.0
Anzeigen:
© 2015 Microsoft