मुझे एक ऐसी ही समस्या थी जहां मैं एक उपकरण लिख रहा था जिसे एक डोमेन पर मशीन चलाने के लिए आवश्यक था और विश्वसनीय कनेक्शन का उपयोग कर किसी अन्य डोमेन पर SQL सर्वर के साथ प्रमाणित किया गया था। इस विषय पर जो कुछ भी मुझे मिल सकता है, उसने कहा कि यह नहीं किया जा सका। इसके बजाय आपको डोमेन में शामिल होना चाहिए, एसक्यूएल प्रमाणीकरण का उपयोग करना चाहिए, कुछ विकल्पों का नाम देने के लिए, केर्बेरोस नामक कुछ चैप के साथ शामिल होना चाहिए, या अपने नेटवर्क लोगों को एक विश्वसनीय रिश्ते को स्थापित करने के लिए प्राप्त करें।
बात है मुझे पता था कि मैं इसे किसी तरह runas का उपयोग कर में काम मिल सकता है क्योंकि मैं इसे SSMS साथ साबित होता:
C:\WINDOWS\system32\runas.exe /netonly /savecred /user:megacorp\joe.bloggs "C:\Program Files\Microsoft SQL Server\90\Tools\Binn\VSShell\Common7\IDE\SqlWb.exe"
/netonly झंडा मुझे स्थानीय पहचान के साथ exe निष्पादित करने के लिए अनुमति दी और रिमोट क्रेडेंशियल्स के साथ नेटवर्क तक पहुंचें, मुझे लगता है, वैसे भी मुझे रिमोट सर्वर से अपेक्षित परिणाम सेट मिला है। समस्या रनस कमांड ने एप्लिकेशन को डीबग करना बहुत मुश्किल बना दिया, और यह अच्छा गंध नहीं हुआ।
using System;
using System.Runtime.InteropServices; // DllImport
using System.Security.Principal; // WindowsImpersonationContext
namespace TestApp
{
class Impersonator
{
// group type enum
enum SECURITY_IMPERSONATION_LEVEL : int
{
SecurityAnonymous = 0,
SecurityIdentification = 1,
SecurityImpersonation = 2,
SecurityDelegation = 3
}
// obtains user token
[DllImport("advapi32.dll", SetLastError = true)]
static extern bool LogonUser(string pszUsername, string pszDomain, string pszPassword,
int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
// closes open handes returned by LogonUser
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
extern static bool CloseHandle(IntPtr handle);
// creates duplicate token handle
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);
WindowsImpersonationContext newUser;
///
/// Attempts to impersonate a user. If successful, returns
/// a WindowsImpersonationContext of the new users identity.
///
/// Username you want to impersonate
/// Logon domain
/// User's password to logon with
///
public Impersonator(string sUsername, string sDomain, string sPassword)
{
// initialize tokens
IntPtr pExistingTokenHandle = new IntPtr(0);
IntPtr pDuplicateTokenHandle = new IntPtr(0);
pExistingTokenHandle = IntPtr.Zero;
pDuplicateTokenHandle = IntPtr.Zero;
// if domain name was blank, assume local machine
if (sDomain == "")
sDomain = System.Environment.MachineName;
try
{
const int LOGON32_PROVIDER_DEFAULT = 0;
// create token
// const int LOGON32_LOGON_INTERACTIVE = 2;
const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
//const int SecurityImpersonation = 2;
// get handle to token
bool bImpersonated = LogonUser(sUsername, sDomain, sPassword,
LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, ref pExistingTokenHandle);
// did impersonation fail?
if (false == bImpersonated)
{
int nErrorCode = Marshal.GetLastWin32Error();
// show the reason why LogonUser failed
throw new ApplicationException("LogonUser() failed with error code: " + nErrorCode);
}
bool bRetVal = DuplicateToken(pExistingTokenHandle, (int)SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, ref pDuplicateTokenHandle);
// did DuplicateToken fail?
if (false == bRetVal)
{
int nErrorCode = Marshal.GetLastWin32Error();
CloseHandle(pExistingTokenHandle); // close existing handle
// show the reason why DuplicateToken failed
throw new ApplicationException("DuplicateToken() failed with error code: " + nErrorCode);
}
else
{
// create new identity using new primary token
WindowsIdentity newId = new WindowsIdentity(pDuplicateTokenHandle);
WindowsImpersonationContext impersonatedUser = newId.Impersonate();
newUser = impersonatedUser;
}
}
finally
{
// close handle(s)
if (pExistingTokenHandle != IntPtr.Zero)
CloseHandle(pExistingTokenHandle);
if (pDuplicateTokenHandle != IntPtr.Zero)
CloseHandle(pDuplicateTokenHandle);
}
}
public void Undo()
{
newUser.Undo();
}
}
}
यह सिर्फ उपयोग करने के लिए:
Impersonator impersonator = new Impersonator("username", "domain", "password");
//Connect to and use SQL server
impersonator.Undo();
अंततः मैं the code project जो सक्रिय निर्देशिका में हेरफेर करने के सत्यापन के बारे में बात कर रहा था पर इस लेख पाया, यहां मुख्य वर्ग है कि प्रतिरूपण करता है मैंने पूर्ववत विधि में जोड़ा है अन्यथा प्रतिरूपण वस्तु एकत्रित कचरा पाने के लिए प्रतिबद्ध है। मैंने LOGON32_LOGON_NEW_CREDENTIALS का उपयोग करने के लिए कोड भी बदल दिया लेकिन यह एक पोक था और इसे काम करने के लिए चला गया; मुझे अभी भी पूरी तरह से समझने की जरूरत है कि यह क्या करता है, मुझे लगता है कि यह रनस पर/नेटोनली ध्वज जैसा ही है। मैं कन्स्ट्रक्टर को थोड़ा तोड़ने जा रहा हूं।
असल में, सवाल स्पष्ट रूप से बताता है कि SQL सर्वर प्रमाणीकरण का उपयोग एक विकल्प नहीं है (कोई डाउनवोट नहीं है, हालांकि ...) – Heinzi