2014-10-16 36 views
1

我的用戶在SPA頁面上幾個小時後即被註銷。雖然,如果他們使用較舊的回發表單,他們永遠不會超時。所以你有上下文,我已經包含了足夠的代碼來爲底部的問題描述提供上下文。使用SPA時,slidingExpiration似乎無法與ASP.NET MVC API一起使用

的Web.config認證

<authentication mode="Forms"> 
    <forms loginUrl="~/Account/Login" timeout="480" slidingExpiration="true" defaultUrl="~" ticketCompatibilityMode="Framework40"/> 
</authentication> 

我的API控制器

namespace my.Controllers 
{ 
    public class ApiMotionController : ApiController 
    { 
     [Authorize(Roles = "Mover"] 
     public IQueryable<Motions> Get() 

JavaScript代碼

(function() { 
'use strict'; 
angular.module('app') 
    .controller('MotionManager', ['$scope', '$http', buildMotionManager]); 

function buildMotionManager($scope, $http) { 
    /*Static Members*/ 
    $scope._whoami = 'MotionManager'; //Used for troubleshooting controller 

    /*Initialization Code*/ 
    getMotions($scope, $http)(); 

    /*Scope methods*/ 
    $scope.refreshMotionsList = getMotions($scope, $http); 
    $scope.addMotion = addMotion($scope, $http); 
    $scope.playMotion = playMotion($scope, $http); 

} 

function getMotions($scope, $http){ 
    return function(){ 
     $http.get('/api/getMotions') 
      .succeed(function(data){ 
       $scope.motionList = data; 
      }) 
      .error(function(data){ 
       console.log('FAIL', data); 
      }); 
    }; 
} 

function addMotion($scope, $http){ 
    //stub. Code not shown here. 
}; 
function playMotion($scope, $http){ 
    //stub. Code not shown here. 
}; 

})(); 

有我在上面的代碼中錯別字,因爲我是從重新輸入它我原始的同時消毒。

代碼確實按預期工作,但問題是經過數小時的工作後,突然發生所有Web API調用失敗並出現401錯誤。也就是說,它們都像用戶現在被取消認證一樣行事。

如上所述,當我使用Web表單甚至MVC表單並重新發布整個頁面時,我無法複製此問題。只有當我使用SPA風格編碼時。我還沒有嘗試過其他的SPA框架,因爲我在這個項目中有6個月的角度定向代碼,所以切換不是一種選擇。

我已經考慮過放置一個iframe,用一個計時器在背景中對錶單對象進行觸發,只是爲了誘使瀏覽器生成適當的表單回傳。我想避免這樣做,因爲它似乎很難。

我發現的唯一的其他關鍵問題是,我看到一堆schannel錯誤被登錄到IIS服務器上的應用程序事件日誌中。他們都是10,10這是沒有很好的記錄。這10個系列在10,10之外有詳細記錄。但是這些建議似乎都沒有奏效,甚至沒有意義。

服務器是IIS 7.5和我試圖此上IIS 8.

應用程序日誌錯誤:

  • 產生致命的警報和發送到遠程端點。這可能會導致連接終止。 TLS協議定義的致命錯誤碼是10。視窗SChannel中錯誤狀態是10。
    • 錯誤狀態:10,警報說明:10
  • 產生致命的警報和發送到遠程端點。這可能會導致連接終止。 TLS協議定義的致命錯誤代碼是40.Windows SChannel錯誤狀態是1205.
  • 從遠程客戶端應用程序收到TLS 1.2連接請求,但服務器不支持客戶端應用程序支持的任何密碼套件。 SSL連接請求失敗。

發現

錯誤代碼40意味着有握手的問題。由於狀態管理是爲我的平臺定製的,因此我決定將其更改爲inproc。到目前爲止,我已經看到錯誤日誌減少了新的錯誤頻率,但消失了。不過,我仍在測試401版問題。

發現後跟進

有證書重發,並清除SCHANNEL錯誤,但問題仍然。

我已經開始使用細齒梳探索標題信息,即使這意味着我必須添加自定義標題信息以伴隨我的服務器調用。

我現在已經包含在所有$ http調用withCredentials: true中,這使我的失敗率降低到了15%左右。這意味着每天的失敗次數降至一次或兩次。

我開始在客戶端觀看我的'auth'cookie,偶爾會發生一些令人困惑的事情。該cookie將在沒有提示的情況下更改,然後又改回。幾乎就像會議從現在開始反彈到新的一樣,然後回到當前。所以我在服務器上的會話表上殺掉了我的清理過程,看看我到了那裏。

我也一直在檢查系統日誌的異常,或SQL超時,什麼也沒有。

開始將所有控制器轉換爲MVC控制器,但在轉換問題(包括使用jSON序列化程序)後遇到轉換問題。當JSON.NET工作得更好時,我仍然不明白堅持使用MS序列化器的決定。

現狀

我最後一次修改是增加filters.Add(new AuthorizeAttribute());FilterConfig.RegisterGlobalFilters功能。

一切仍然失敗。在調查了IIS日誌之後,我仍然看到所有的事情都得到了認證。

  • FF在Windows - 失敗
  • Chrome Windows版 - 失敗
  • 上的Chrome瀏覽的Droid - 失敗
  • Safari瀏覽器在iPad上 - 失敗
  • IE在Windows上 - 失敗

12/10發現

我已經找到了真正的問題。 MVC控制器中的身份驗證與Web API控制器不兼容。所以當我使用MVC控制器進行身份驗證時,Web API控制器基本上忽略它,並最終超時進行身份驗證。

最新發現

顯然,當asp.net工作進程關閉,並重新啓動,它會得到數據庫架構並不存在一個錯誤的標誌。所以我刪除了檢查,所有的讀寫操作都開始正常工作。有趣的是,當mvc控制器認證失敗時,api控制器會僞造一個新的cookie。這就像它正在創建一個新的提供者實例。然而,我找不到第二個實例,所以我必須假設現有的提供者正在被複制。被測試

現在,我已刪除了DB測試

修復,我現在在長遠來看,測試中的問題。每個長期運行比工作進程保持活動時間長,但比會話超時短。

發現這個錯誤

的基石顯然IIS Express時隱藏的錯誤,因爲它似乎沒有外部工作進程採取行動。所以我將測試環境移到我的本地IIS服務器上。

+0

這似乎並不是一個角度問題,因爲它通過WebApi處理身份驗證。一旦你超時了,你如何重新認證? – dannypaz 2014-10-16 20:07:35

+0

它可以與Web表單/ mvc表單一起工作的原因之一是由於服務器管理你的狀態/ cookie。你已經解耦了(使用WebApi和Angular),需要從服務器重新進行身份驗證。 – dannypaz 2014-10-16 20:10:01

+0

livepo,一旦他們註銷,我強制他們導航到登錄屏幕,並重新進行身份驗證。 因此,寧靜的電話沒有維護會話cookie?我認爲這五個動詞是服務動詞的全面實施。在服務器上,我可以訪問apicontroller中的cookie。 – Brian 2014-10-16 21:23:24

回答

0

它看起來像有一些引起了我的問題的幾個問題,每一個細分的位置:

  1. IIS Express時不關閉會話的完整的IIS會以同樣的方式。
    1. 因此,我將應用程序移動到本地IIS,並將日誌記錄添加到所有內容。
  2. ASP.NET工作進程會在每次調用API控制器時啓動新的提供程序實例。
    1. 這將導致每次調用都有一個新的模式檢查。 MVC控制器只會在初次啓動時進行一次這種檢查。
    2. 由於我的提供者與我的應用程序模式結婚,我只是禁用了模式檢查。
  3. 必須告訴角必須對cookie進行編組。
    1. 於是我說:cfg: { withCredentials: true, responseType: "json" }
    2. 響應類型是涵蓋偶爾的問題,我會看到「文本/文本」。現在我總是看到'application/json'。這似乎是一個瀏覽器問題,主要與IE。
  4. 我還必須將config.MapHttpAttributeRoutes();添加到我的WebApiConfig類的註冊方法中。

使用所有這些,我能夠發現問題的核心是每個api調用導致我的安全提供程序重新測試架構,我的MVC控制器設置爲在測試之後抑制該測試第一次加載。測試總是失敗,因爲我不得不擴展一些表格,但我不需要改變模型。

解決方法:我從提供者刪除了測試。由於提供程序與應用程序的其他部分緊密相關,因此將其視爲典型的ASP.NET成員資格提供程序似乎不合邏輯。這是我不需要的最重要的功能。

第二個好處是,我獲得了一點點的表現。

+0

'responseType:「json」'應該謹慎使用,特別是如果你返回未包裝的字符串,GUID,INT或其他單個值。 如果返回主體看起來像「some value」而不是「{」value「:」某個值「}」,那麼responseType:「json」在Chrome和Firefox上將失敗。 – Brian 2014-12-16 22:39:27

相關問題