0

Silverlight アプリの次のコードを使用して、ファイルをネットワーク パスにアップロードしようとしました。

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);
   }
 }
}

VSビルトインWebサーバーでデバッグモードで実行すると、正常に動作します。SL 側では、次のような URL でこのハンドラーを呼び出します。

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

次に、このアプリをローカル IIS に公開し、URL を次のように変更します。http://localhost/Mysite/FileUpload.ashx

その後、アプリを再度実行します。もう機能しませんが、エラーはありません。

File.Createを呼び出すための資格情報が異なるためだと思います。したがって、ハンドラーで特定の資格情報を使用して、ファイルを宛先に配置したいと考えています。

File.Create の資格情報を使用するには?

4

1 に答える 1

0

ユーザーになりすます必要があると思います。以下のコードでそれを行う必要があります。基本的に、ドメイン、ユーザー、およびパスワードを収集し、ImpersonationMgr クラスをインスタンス化します。次に、BeginImpersonation メソッドを呼び出します。その後、対応する WriteFile メソッドを呼び出します。偽装が有効な場合、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);
  }
}

アップデート

   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);
      }
   }
于 2012-07-05T17:08:05.193 に答える