NamedPipeServerStream.RunAsClient(PipeStreamImpersonationWorker) Methode
Definition
Wichtig
Einige Informationen beziehen sich auf Vorabversionen, die vor dem Release ggf. grundlegend überarbeitet werden. Microsoft übernimmt hinsichtlich der hier bereitgestellten Informationen keine Gewährleistungen, seien sie ausdrücklich oder konkludent.
Ruft einen Delegaten auf, während die Identität des Clients imitiert wird.
public:
void RunAsClient(System::IO::Pipes::PipeStreamImpersonationWorker ^ impersonationWorker);
public void RunAsClient (System.IO.Pipes.PipeStreamImpersonationWorker impersonationWorker);
[System.Security.SecurityCritical]
public void RunAsClient (System.IO.Pipes.PipeStreamImpersonationWorker impersonationWorker);
member this.RunAsClient : System.IO.Pipes.PipeStreamImpersonationWorker -> unit
[<System.Security.SecurityCritical>]
member this.RunAsClient : System.IO.Pipes.PipeStreamImpersonationWorker -> unit
Public Sub RunAsClient (impersonationWorker As PipeStreamImpersonationWorker)
Parameter
- impersonationWorker
- PipeStreamImpersonationWorker
Der Delegat, der eine aufzurufende Methode angibt.
- Attribute
Ausnahmen
Es wurden noch keine Pipeverbindungen hergestellt.
- oder -
Die verbundene Pipe wurde bereits getrennt.
- oder -
Das Pipehandle wurde nicht festgelegt.
Die Pipe ist geschlossen.
Beispiele
Das folgende Beispiel veranschaulicht eine Methode zum Erstellen eines Pipeservers, der auf mehrere gleichzeitige Clientanforderungen reagieren kann, und eine Methode für den Clientidentitätswechsel. In diesem Beispiel wird ein NamedPipeServerStream Objekt in einem übergeordneten Prozess erstellt, der dann mehrere Threads erstellt, die auf die Verbindung von NamedPipeClientStream Objekten warten. Nachdem ein Client verbunden wurde, gibt er einen Dateinamen an den Server an, und der Inhalt dieser Datei wird gelesen und an den Client zurückgesendet. Da der NamedPipeServerStream beim Öffnen der Datei die Identität des Clients angibt, kann der Client nur Dateien anfordern, für die er über ausreichende Berechtigungen zum Öffnen verfügt.
#using <System.Core.dll>
using namespace System;
using namespace System::IO;
using namespace System::IO::Pipes;
using namespace System::Text;
using namespace System::Threading;
// Defines the data protocol for reading and writing strings on our stream
public ref class StreamString
{
private:
Stream^ ioStream;
UnicodeEncoding^ streamEncoding;
public:
StreamString(Stream^ ioStream)
{
this->ioStream = ioStream;
streamEncoding = gcnew UnicodeEncoding();
}
String^ ReadString()
{
int len;
len = ioStream->ReadByte() * 256;
len += ioStream->ReadByte();
array<Byte>^ inBuffer = gcnew array<Byte>(len);
ioStream->Read(inBuffer, 0, len);
return streamEncoding->GetString(inBuffer);
}
int WriteString(String^ outString)
{
array<Byte>^ outBuffer = streamEncoding->GetBytes(outString);
int len = outBuffer->Length;
if (len > UInt16::MaxValue)
{
len = (int)UInt16::MaxValue;
}
ioStream->WriteByte((Byte)(len / 256));
ioStream->WriteByte((Byte)(len & 255));
ioStream->Write(outBuffer, 0, len);
ioStream->Flush();
return outBuffer->Length + 2;
}
};
// Contains the method executed in the context of the impersonated user
public ref class ReadFileToStream
{
private:
String^ fn;
StreamString ^ss;
public:
ReadFileToStream(StreamString^ str, String^ filename)
{
fn = filename;
ss = str;
}
void Start()
{
String^ contents = File::ReadAllText(fn);
ss->WriteString(contents);
}
};
public ref class PipeServer
{
private:
static int numThreads = 4;
public:
static void Main()
{
int i;
array<Thread^>^ servers = gcnew array<Thread^>(numThreads);
Console::WriteLine("\n*** Named pipe server stream with impersonation example ***\n");
Console::WriteLine("Waiting for client connect...\n");
for (i = 0; i < numThreads; i++)
{
servers[i] = gcnew Thread(gcnew ThreadStart(&ServerThread));
servers[i]->Start();
}
Thread::Sleep(250);
while (i > 0)
{
for (int j = 0; j < numThreads; j++)
{
if (servers[j] != nullptr)
{
if (servers[j]->Join(250))
{
Console::WriteLine("Server thread[{0}] finished.", servers[j]->ManagedThreadId);
servers[j] = nullptr;
i--; // decrement the thread watch count
}
}
}
}
Console::WriteLine("\nServer threads exhausted, exiting.");
}
private:
static void ServerThread()
{
NamedPipeServerStream^ pipeServer =
gcnew NamedPipeServerStream("testpipe", PipeDirection::InOut, numThreads);
int threadId = Thread::CurrentThread->ManagedThreadId;
// Wait for a client to connect
pipeServer->WaitForConnection();
Console::WriteLine("Client connected on thread[{0}].", threadId);
try
{
// Read the request from the client. Once the client has
// written to the pipe its security token will be available.
StreamString^ ss = gcnew StreamString(pipeServer);
// Verify our identity to the connected client using a
// string that the client anticipates.
ss->WriteString("I am the one true server!");
String^ filename = ss->ReadString();
// Read in the contents of the file while impersonating the client.
ReadFileToStream^ fileReader = gcnew ReadFileToStream(ss, filename);
// Display the name of the user we are impersonating.
Console::WriteLine("Reading file: {0} on thread[{1}] as user: {2}.",
filename, threadId, pipeServer->GetImpersonationUserName());
pipeServer->RunAsClient(gcnew PipeStreamImpersonationWorker(fileReader, &ReadFileToStream::Start));
}
// Catch the IOException that is raised if the pipe is broken
// or disconnected.
catch (IOException^ e)
{
Console::WriteLine("ERROR: {0}", e->Message);
}
pipeServer->Close();
}
};
int main()
{
PipeServer::Main();
}
using System;
using System.IO;
using System.IO.Pipes;
using System.Text;
using System.Threading;
public class PipeServer
{
private static int numThreads = 4;
public static void Main()
{
int i;
Thread[] servers = new Thread[numThreads];
Console.WriteLine("\n*** Named pipe server stream with impersonation example ***\n");
Console.WriteLine("Waiting for client connect...\n");
for (i = 0; i < numThreads; i++)
{
servers[i] = new Thread(ServerThread);
servers[i].Start();
}
Thread.Sleep(250);
while (i > 0)
{
for (int j = 0; j < numThreads; j++)
{
if (servers[j] != null)
{
if (servers[j].Join(250))
{
Console.WriteLine("Server thread[{0}] finished.", servers[j].ManagedThreadId);
servers[j] = null;
i--; // decrement the thread watch count
}
}
}
}
Console.WriteLine("\nServer threads exhausted, exiting.");
}
private static void ServerThread(object data)
{
NamedPipeServerStream pipeServer =
new NamedPipeServerStream("testpipe", PipeDirection.InOut, numThreads);
int threadId = Thread.CurrentThread.ManagedThreadId;
// Wait for a client to connect
pipeServer.WaitForConnection();
Console.WriteLine("Client connected on thread[{0}].", threadId);
try
{
// Read the request from the client. Once the client has
// written to the pipe its security token will be available.
StreamString ss = new StreamString(pipeServer);
// Verify our identity to the connected client using a
// string that the client anticipates.
ss.WriteString("I am the one true server!");
string filename = ss.ReadString();
// Read in the contents of the file while impersonating the client.
ReadFileToStream fileReader = new ReadFileToStream(ss, filename);
// Display the name of the user we are impersonating.
Console.WriteLine("Reading file: {0} on thread[{1}] as user: {2}.",
filename, threadId, pipeServer.GetImpersonationUserName());
pipeServer.RunAsClient(fileReader.Start);
}
// Catch the IOException that is raised if the pipe is broken
// or disconnected.
catch (IOException e)
{
Console.WriteLine("ERROR: {0}", e.Message);
}
pipeServer.Close();
}
}
// Defines the data protocol for reading and writing strings on our stream
public class StreamString
{
private Stream ioStream;
private UnicodeEncoding streamEncoding;
public StreamString(Stream ioStream)
{
this.ioStream = ioStream;
streamEncoding = new UnicodeEncoding();
}
public string ReadString()
{
int len = 0;
len = ioStream.ReadByte() * 256;
len += ioStream.ReadByte();
byte[] inBuffer = new byte[len];
ioStream.Read(inBuffer, 0, len);
return streamEncoding.GetString(inBuffer);
}
public int WriteString(string outString)
{
byte[] outBuffer = streamEncoding.GetBytes(outString);
int len = outBuffer.Length;
if (len > UInt16.MaxValue)
{
len = (int)UInt16.MaxValue;
}
ioStream.WriteByte((byte)(len / 256));
ioStream.WriteByte((byte)(len & 255));
ioStream.Write(outBuffer, 0, len);
ioStream.Flush();
return outBuffer.Length + 2;
}
}
// Contains the method executed in the context of the impersonated user
public class ReadFileToStream
{
private string fn;
private StreamString ss;
public ReadFileToStream(StreamString str, string filename)
{
fn = filename;
ss = str;
}
public void Start()
{
string contents = File.ReadAllText(fn);
ss.WriteString(contents);
}
}
Imports System.IO
Imports System.IO.Pipes
Imports System.Text
Imports System.Threading
Public Class PipeServer
Private Shared numThreads As Integer = 4
Public Shared Sub Main()
Dim i As Integer
Dim servers(numThreads) As Thread
Console.WriteLine(Environment.NewLine + "*** Named pipe server stream with impersonation example ***" + Environment.NewLine)
Console.WriteLine("Waiting for client connect..." + Environment.NewLine)
For i = 0 To numThreads - 1
servers(i) = New Thread(AddressOf ServerThread)
servers(i).Start()
Next i
Thread.Sleep(250)
While i > 0
For j As Integer = 0 To numThreads - 1
If Not(servers(j) Is Nothing) Then
if servers(j).Join(250)
Console.WriteLine("Server thread[{0}] finished.", servers(j).ManagedThreadId)
servers(j) = Nothing
i -= 1 ' decrement the thread watch count
End If
End If
Next j
End While
Console.WriteLine(Environment.NewLine + "Server threads exhausted, exiting.")
End Sub
Private Shared Sub ServerThread(data As Object)
Dim pipeServer As New _
NamedPipeServerStream("testpipe", PipeDirection.InOut, numThreads)
Dim threadId As Integer = Thread.CurrentThread.ManagedThreadId
' Wait for a client to connect
pipeServer.WaitForConnection()
Console.WriteLine("Client connected on thread[{0}].", threadId)
Try
' Read the request from the client. Once the client has
' written to the pipe its security token will be available.
Dim ss As new StreamString(pipeServer)
' Verify our identity to the connected client using a
' string that the client anticipates.
ss.WriteString("I am the one true server!")
Dim filename As String = ss.ReadString()
' Read in the contents of the file while impersonating the client.
Dim fileReader As New ReadFileToStream(ss, filename)
' Display the name of the user we are impersonating.
Console.WriteLine("Reading file: {0} on thread[{1}] as user: {2}.",
filename, threadId, pipeServer.GetImpersonationUserName())
pipeServer.RunAsClient(AddressOf fileReader.Start)
' Catch the IOException that is raised if the pipe is broken
' or disconnected.
Catch e As IOException
Console.WriteLine("ERROR: {0}", e.Message)
End Try
pipeServer.Close()
End Sub
End Class
' Defines the data protocol for reading and writing strings on our stream
Public Class StreamString
Private ioStream As Stream
Private streamEncoding As UnicodeEncoding
Public Sub New(ioStream As Stream)
Me.ioStream = ioStream
streamEncoding = New UnicodeEncoding(False, False)
End Sub
Public Function ReadString() As String
Dim len As Integer = 0
len = CType(ioStream.ReadByte(), Integer) * 256
len += CType(ioStream.ReadByte(), Integer)
Dim inBuffer As Array = Array.CreateInstance(GetType(Byte), len)
ioStream.Read(inBuffer, 0, len)
Return streamEncoding.GetString(inBuffer)
End Function
Public Function WriteString(outString As String) As Integer
Dim outBuffer() As Byte = streamEncoding.GetBytes(outString)
Dim len As Integer = outBuffer.Length
If len > UInt16.MaxValue Then
len = CType(UInt16.MaxValue, Integer)
End If
ioStream.WriteByte(CType(len \ 256, Byte))
ioStream.WriteByte(CType(len And 255, Byte))
ioStream.Write(outBuffer, 0, outBuffer.Length)
ioStream.Flush()
Return outBuffer.Length + 2
End Function
End Class
' Contains the method executed in the context of the impersonated user
Public Class ReadFileToStream
Private fn As String
Private ss As StreamString
Public Sub New(str As StreamString, filename As String)
fn = filename
ss = str
End Sub
Public Sub Start()
Dim contents As String = File.ReadAllText(fn)
ss.WriteString(contents)
End Sub
End Class
Hinweise
Die Berechtigungen des verbindenden Clients werden auf den Remoteserver angewendet. Wenn der verbindende Client beispielsweise versucht, den Inhalt einer Datei auf dem Server anzufordern, kann der Client nur Dateien anfordern, für die er über ausreichende Berechtigungen zum Öffnen verfügt.