Я довольно долго искал простой и стандартный путь для того чтобы произвести аутентификацию пользователя (текущий пользователь - вы не знаете его пароля и пользователь заданный при помощи NetworkCredential) на удаленном компьютере. Хотел уже было все написать ручками через AcquireCredentialsHandle/InitializeSecurityContext/AcceptSecurityContext/CompleteAuthToken, но совсем неожиданно нашел NegotiateStream - который и занимается данным непростым процессом. По сему поводу написал маленький примерчик (пример работает только в пределах одного компьютера, если хотите большего, то замените NamedPipeXxxStream на Socket).
namespace AuthTest
{
public static class Constants
{
public const string PipeName = "AuthTest";
}
}
using System;
using System.IO.Pipes;
using System.Net;
using System.Net.Security;
using System.Security.Principal;
namespace AuthTest.Client
{
internal class Program
{
private static void Main(string[] args)
{
try
{
Console.WriteLine("AuthTest Client Copyright (C) 2010 Mikhail Pilin");
using (var stream = new NamedPipeClientStream(Constants.PipeName))
{
stream.Connect();
using (var negotiateStream = new NegotiateStream(stream, true))
negotiateStream.AuthenticateAsClient(
GetCredential(args),
"",
ProtectionLevel.EncryptAndSign,
TokenImpersonationLevel.Delegation);
}
Console.WriteLine("Done");
}
catch (Exception e)
{
Console.Error.WriteLine(e);
}
}
private static NetworkCredential GetCredential(string[] args)
{
switch (args.Length)
{
case 0:
return (NetworkCredential) CredentialCache.DefaultCredentials;
case 1:
return new NetworkCredential(args[0], "");
case 2:
return new NetworkCredential(args[0], args[1]);
case 3:
return new NetworkCredential(args[0], args[1], args[2]);
default:
throw new ArgumentException();
}
}
}
}
using System;
using System.IO.Pipes;
using System.Net.Security;
using System.Security.Principal;
namespace AuthTest.Server
{
internal class Program
{
private static void Main()
{
try
{
Console.WriteLine("AuthTest Server Copyright (C) 2010 Mikhail Pilin");
using (var stream = new NamedPipeServerStream(Constants.PipeName))
{
stream.WaitForConnection();
using (var negotiateStream = new NegotiateStream(stream, true))
{
negotiateStream.AuthenticateAsServer();
var remoteIdentity = (WindowsIdentity) negotiateStream.RemoteIdentity;
Console.WriteLine("Name: {0}", remoteIdentity.Name);
Console.WriteLine("User: {0}", remoteIdentity.User);
Console.WriteLine("AuthenticationType: {0}", remoteIdentity.AuthenticationType);
Console.WriteLine("ImpersonationLevel: {0}", remoteIdentity.ImpersonationLevel);
Console.WriteLine("IsAuthenticated: {0}", remoteIdentity.IsAuthenticated);
Console.WriteLine("IsAnonymous: {0}", remoteIdentity.IsAnonymous);
Console.WriteLine("IsSystem: {0}", remoteIdentity.IsSystem);
Console.WriteLine("IsGuest: {0}", remoteIdentity.IsGuest);
}
}
Console.WriteLine("Done");
}
catch (Exception e)
{
Console.Error.WriteLine(e);
}
}
}
}
No comments:
Post a Comment