Я довольно долго искал простой и стандартный путь для того чтобы произвести аутентификацию пользователя (текущий пользователь - вы не знаете его пароля и пользователь заданный при помощи 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