2017-02-27 142 views
0

我有一個MVC應用程序和一個關聯的Web API項目,它們都承載在IIS上的遠程服務器上。他們共享相同的應用程序池。每當我嘗試從MVC應用程序調用Web API時,我都會收到一個403錯誤,它似乎來自HttpClientHandler傳遞的錯誤憑據。我有使用集成Windows身份驗證從MVC應用程序調用Web API

UseDefaultCredentials = true 

,我已經嘗試設置

Credentials = CredentialCache.DefaultNetworkCredentials 

但是這些都使API請求要經過。

設置應用程序池使用我的AD用戶名/密碼允許所有API請求通過,並且直接從Postman調用API可以正確返回數據。

我的假設是IIS AppPool [Pool Name]在請求中獲得轉發,並且永遠不會傳遞正確的憑據。反正有沒有使API不安全(即只有幾個域組應該可以訪問它)?

一個電話,我對API從MVC應用

public async Task<HttpResponseMessage> CreateIncident(Incident model) 
    { 
     using (var client = new HttpClient(new HttpClientHandler { UseDefaultCredentials = true })) 
     { 
      var newIncident = new StringContent(JsonConvert.SerializeObject(model), Encoding.UTF8, "application/json"); 
      var response = await client.PostAsync(hostUri, newIncident); 
      return response; 
     } 
    } 
+0

您是否正在通過代理? – joshmcode

+0

不,這是全部託管在內部服務器上,並且所有呼叫都將通過該服務器完全進行。沒有代理。就像我說的那樣,郵遞員和我的電腦直接調用了API,但似乎.NET Core不能模擬這些請求,並且我希望最近有人能夠提供更新的更新解決方案比在.NET Core中已經有點過時的6個月以前的版本中的一些更加容易。 –

回答

1

在沒有看到代碼很難說的例子。您是否嘗試過不設置Credentials參數?我會運行fiddler並比較MVC應用程序和Postman發送的請求。

+0

我看着Fiddler的結果。由於集成Windows身份驗證,郵差甚至沒有進行任何協商,因此服務器會自動確定我的登錄憑據。至於MVC應用程序,它發送協商授權與請求,這就是返回一個401.這就是爲什麼我認爲API獲取IIS AppPool信息並將其作爲憑據發送。我也在這個問題中拋出了一些示例代碼。 –

+0

你試過刪除UseDefaultCredentials = true嗎? –

+0

是的,它似乎沒有任何影響。還嘗試做PreAuth = false和Credentials設置爲某事。可能只是與大衛的解決方案,並有應用程序不完全是核心。 –

3

沒有更多信息,很難肯定地說,但問題可能是由於您嘗試使用雙跳身份驗證。

  1. 客戶端應用程序(瀏覽器在一個網站的情況下) 驗證客戶端發送
  2. 認證到該服務器的用戶(MVC應用)
  3. MVC應用然後試圖沿着通過認證到web服務

當我需要做類似的任務時,我無法讓HttpClient工作。我試過了這個問題的一些建議解決方案,How to get HttpClient to pass credentials along with the request?。雖然這是信息 - 具體而言,BlackSpy的回答這部分解釋了爲什麼:

你所要做的就是讓NTLM轉發到下一個服務器,它不能做身份 - 它只能做模擬只允許您訪問本地資源。

我結束了使用Web客戶端(有必要定向.NET架構)的東西在MVC應用程序是這樣的(從下載的網頁API文件,在這種情況下):

private async Task GetFileAsync(Identity identity, string serviceAddress, Stream stream) 
{ 
    var windowsIdentity = Identity as WindowsIdentity; 

    if (windowsIdentity == null) 
    { 
     throw new InvalidOperationException("Identity not a valid windows identity."); 
    } 

    using (windowsIdentity.Impersonate()) 
    { 
     using (var client = new WebClient { UseDefaultCredentials = true }) 
     { 
      var fileData = await client.DownloadDataTaskAsync(serviceAddress); 
      await stream.WriteAsync(fileData, 0, fileData.Length); 
      stream.Seek(0, SeekOrigin.Begin); 
     } 
    } 
} 

雖然針對完整框架的要求可以防止它成爲一個.NET核心解決方案,但它看起來像是從那時起被添加的。

Add WebClient to new System.Net.WebClient contract

這PR端口系統。Net.WebClient到corefx。代碼大部分來自桌面,然後進行一些風格清理。唯一主要的代碼重寫是刪除數百行復雜的基於APM回調的代碼,並用幾個核心異步方法替代它。還有很多可以完成的清理工作,但從功能上來說這已經足夠了。

+0

我看到了這個解決方案(並且讀了太多關於雙跳的東西),但我不認爲Web客戶端在Core中。他們將它合併到存儲庫中,但據我所知它從未包含在任何RC或預覽中,並且我無法在Visual Studio中引用它。我希望有人會有一個更新的模擬實現,因爲我讀過的另一個Stack Overflow線程有一個過時的解決方案,不再有效。我不想回頭指向.NET Framework,但這也是可能會降低的。謝謝! –

+0

嘿大衛,我終於找到了我一直在尋找的解決方案(是的...它花了一段時間)。您可以在這裏找到GitHub問題討論,並且用戶ilanc在討論底部發布了一個示例回購方式的鏈接。 https://github.com/aspnet/Home/issues/1805 –

相關問題