/// <summary> /// Registers a <see cref="NetworkCredential"/> for a given <see cref="ResourcePath"/> /// </summary> /// <param name="path"> /// For this <see cref="ResourcePath"/> and all subpaths the <see cref="credential"/> is impersonated, /// assuming that no better matching path is registered. /// </param> /// <param name="credential"><see cref="NetworkCredential"/> to impersonate for accessing <paramref name="path"/></param> /// <returns><c>true</c> if registration was successful; otherwise <c>false</c></returns> public bool TryRegisterCredential(ResourcePath path, NetworkCredential credential) { _debugLogger.Info("ImpersonationService: Trying to register credential (User: '******' Domain: '{1}') for ResourcePath '{2}'", credential.UserName, credential.Domain, path); // If there is already a credential registered for exactly the same ResourcePath, // we unregister the old credential and log a warning. It should have been // unregistered with TryUnregisterCredential before. WindowsIdentityWrapper oldIdWrapper; if (_ids.TryRemove(path, out oldIdWrapper)) { _debugLogger.Warn("ImpersonationService: There was already a credential registered For ResourcePath '{0}'. The old credential was unregistered.", path); oldIdWrapper.Dispose(); } var logonHelper = new LogonHelper(_debugLogger); WindowsIdentity id; // We use LogonType.NewCredentials because this logon type allows the caller to clone its current token // and specify new credentials only for outbound connections. The new logon session has the same local // identifier but uses different credentials for other network connections. // This logon type is only supported by LogonProvider.WinNt50. if (logonHelper.TryLogon(credential, LogonHelper.LogonType.NewCredentials, LogonHelper.LogonProvider.WinNt50, out id)) { var idWrapper = new WindowsIdentityWrapper(id, credential); if (!_ids.TryAdd(path, idWrapper)) { // In a multithreaded environment, a new credential could have been added // despite the TryUnregisterCredential call above in the meantime. _debugLogger.Error("ImpersonationService: For ResourcePath '{0}' there was already a credential registered. Cannot register new credential.", path); idWrapper.Dispose(); return(false); } _debugLogger.Info("ImpersonationService: Successfully registered credential for ResourcePath '{0}': User: '******' (Domain: '{2}')", path, idWrapper.UserName, idWrapper.Domain); return(true); } _debugLogger.Error("ImpersonationService: Could not register credential for ResourcePath '{0}': User: '******' (Domain: '{2}')", path, credential.UserName, credential.Domain); return(false); }
/// <summary> /// Registers a <see cref="NetworkCredential"/> for a given <see cref="ResourcePath"/> /// </summary> /// <param name="path"> /// For this <see cref="ResourcePath"/> and all subpaths the <see cref="credential"/> is impersonated, /// assuming that no better matching path is registered. /// </param> /// <param name="credential"><see cref="NetworkCredential"/> to impersonate for accessing <paramref name="path"/></param> /// <returns><c>true</c> if registration was successful; otherwise <c>false</c></returns> public bool TryRegisterCredential(ResourcePath path, NetworkCredential credential) { _debugLogger.Info("ImpersonationService: Trying to register credential (User: '******' Domain: '{1}') for ResourcePath '{2}'", credential.UserName, credential.Domain, path); // If there is already a credential registered for exactly the same ResourcePath, // we unregister the old credential and log a warning. It should have been // unregistered with TryUnregisterCredential before. WindowsIdentityWrapper oldIdWrapper; if (_ids.TryRemove(path, out oldIdWrapper)) { _debugLogger.Warn("ImpersonationService: There was already a credential registered For ResourcePath '{0}'. The old credential was unregistered.", path); oldIdWrapper.Dispose(); } var logonHelper = new LogonHelper(_debugLogger); WindowsIdentity id; // We use LogonType.NewCredentials because this logon type allows the caller to clone its current token // and specify new credentials only for outbound connections. The new logon session has the same local // identifier but uses different credentials for other network connections. // This logon type is only supported by LogonProvider.WinNt50. if (logonHelper.TryLogon(credential, LogonHelper.LogonType.NewCredentials, LogonHelper.LogonProvider.WinNt50, out id)) { var idWrapper = new WindowsIdentityWrapper(id, credential); if(!_ids.TryAdd(path, idWrapper)) { // In a multithreaded environment, a new credential could have been added // despite the TryUnregisterCredential call above in the meantime. _debugLogger.Error("ImpersonationService: For ResourcePath '{0}' there was already a credential registered. Cannot register new credential.", path); idWrapper.Dispose(); return false; } _debugLogger.Info("ImpersonationService: Successfully registered credential for ResourcePath '{0}': User: '******' (Domain: '{2}')", path, idWrapper.UserName, idWrapper.Domain); return true; } _debugLogger.Error("ImpersonationService: Could not register credential for ResourcePath '{0}': User: '******' (Domain: '{2}')", path, credential.UserName, credential.Domain); return false; }