我的用戶在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服務器上。
這似乎並不是一個角度問題,因爲它通過WebApi處理身份驗證。一旦你超時了,你如何重新認證? – dannypaz 2014-10-16 20:07:35
它可以與Web表單/ mvc表單一起工作的原因之一是由於服務器管理你的狀態/ cookie。你已經解耦了(使用WebApi和Angular),需要從服務器重新進行身份驗證。 – dannypaz 2014-10-16 20:10:01
livepo,一旦他們註銷,我強制他們導航到登錄屏幕,並重新進行身份驗證。 因此,寧靜的電話沒有維護會話cookie?我認爲這五個動詞是服務動詞的全面實施。在服務器上,我可以訪問apicontroller中的cookie。 – Brian 2014-10-16 21:23:24