2012-07-05 1 views
0

나는 실버 라이트 응용 프로그램에 대한 다음과 같은 코드로 네트워크 경로에 파일을 업로드하려고 : I 내장 웹 서버 VS와 디버그 모드에서 실행할 때HTTP 처리기 ashx에서 네트워크 경로에 파일을 업로드하는 방법은 무엇입니까?

public void ProcessRequest (HttpContext context) 
{ 
    //..... 
    using (FileStream fs = File.Create(@"\\Server\Folder\" + filename))    
{ 
    byte[] buffer = new byte[4096]; 
    int bytesRead; 
    while ((bytesRead = context.Request.InputStream.Read(buffer, 0, buffer.Length)) != 0) 
    { 
     fs.Write(buffer, 0, bytesRead); 
    } 
} 
} 

그것은 잘 작동합니다. 그럼 난 다시 응용 프로그램을 실행 현지 IIS에이 응용 프로그램을 게시하고 http://localhost/Mysite/FileUpload.ashx

에 URL을 변경

UriBuilder ub = new UriBuilder("http://localhost:38700/FileUpload.ashx"); 

: SL 측면에서, 내가 좋아하는 URL과 함께이 핸들러를 호출합니다. 더 이상 작동하지 않지만 오류는 발생하지 않습니다.

다른 신임장이 File.Create를 호출하기 때문일 것입니다. 그래서 처리기에서 특정 자격 증명을 사용하여 대상에 파일을 저장하려고합니다.

File.Create에 대한 자격 증명을 사용하는 방법은 무엇입니까?

답변

0

사용자를 가장해야한다고 생각합니다. 아래 코드는 그렇게해야합니다. 본질적으로 도메인, 사용자 및 암호를 수집하고 ImpersonationMgr 클래스를 인스턴스화합니다. 그런 다음 BeginImpersonation 메서드를 호출합니다. 그 후 원하는 WriteFile 메서드를 호출하십시오. Impersonation이 사용 가능한 경우 WriteFile 메서드가 어설 션합니다. 삭제 및 이동과 같은 다른 파일 방법에 대해 유사한 패턴을 따를 수 있습니다.

public class ImpersonationMgr : IDisposable 

    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
    public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, 
             int dwLogonProvider, out SafeTokenHandle phToken); 

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)] 
    public static extern bool CloseHandle(IntPtr handle); 

    private const int LOGON32_PROVIDER_DEFAULT = 0; 
    private const int LOGON32_LOGON_NEW_CREDENTIALS = 9; 

    private readonly string userName = string.Empty; 
    private readonly string domainName = string.Empty; 
    private readonly string password = string.Empty; 

    private SafeTokenHandle safeTokenHandle = null; 
    private WindowsImpersonationContext impersonatedUser = null; 

    public ImpersonationMgr(string userName, string domainName, string password) 
    { 
    this.userName = userName; 
    this.domainName = domainName; 
    this.password = password; 
    } 

    public void BeginImpersonation() 
    { 
    bool returnValue = LogonUser(userName, domainName, password, LOGON32_LOGON_NEW_CREDENTIALS, 
            LOGON32_PROVIDER_DEFAULT, out safeTokenHandle); 
    if (returnValue == false) 
    { 
     int ret = Marshal.GetLastWin32Error(); 
     throw new System.ComponentModel.Win32Exception(ret); 
    } 

    impersonatedUser = WindowsIdentity.Impersonate(safeTokenHandle.DangerousGetHandle()); 
    } 

    private void AssertImpersonationIsEnabled() 
    { 
    if(safeTokenHandle == null || impersonatedUser == null) 
    { 
     throw new UnauthorizedAccessException("You must call the BeginImpersonation method before attempting file write access."); 
    } 
    } 

    public void WriteFile(string pathToFile, string fileContents) 
    { 
    AssertImpersonationIsEnabled(); 
    using (FileStream fileStream = File.Open(pathToFile, FileMode.CreateNew)) 
    { 
     using (StreamWriter fileWriter = new StreamWriter(fileStream)) 
     { 
      fileWriter.Write(fileContents); 
     } 
    } 
    } 

    public void WriteFile(string pathToFile, byte[] fileContents) 
    { 
    AssertImpersonationIsEnabled(); 
    using (FileStream fileStream = new FileStream(pathToFile, FileMode.Create)) 
    { 
     fileStream .Write(fileContents, 0, fileContents.Length); 
     fileStream .Flush();   
    } 
    } 

    public void Dispose() 
    { 
    Dispose(true); 
    GC.SuppressFinalize(this); 
    } 
} 

UPDATE

public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid 
    { 
     private SafeTokenHandle() 
     : base(true) 
     { 
     } 


     [DllImport("kernel32.dll")] 
     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
     [SuppressUnmanagedCodeSecurity] 
     [return: MarshalAs(UnmanagedType.Bool)] 
     private static extern bool CloseHandle(IntPtr handle); 

     protected override bool ReleaseHandle() 
     { 
     return CloseHandle(handle); 
     } 
    } 
+0

와우. 쉬운 일이 아닌 것처럼 보입니다. 그것을 시도했다. 웹 프로젝트에 그것을 넣어 SafeTokenHandle를 사용할 수없는 발견했다. .NET 1/2/3/4 용입니다. .NET Framework 4와 함께 VS 2010을 사용하고 4.5로 이동할 것입니다. – KentZhou

+0

오, 기다려 ... 내가 코드를 빠뜨린 것 같아. 감사 업데이트 – Josh

+0

을 참조하십시오. 더 많은 질문 : 핸들에 대한 정의는 어디에 있습니까? Dispose를 호출 할 수 있습니다. – KentZhou