javascript - 与SPA一起使用时,与ASP.NET MVC API一起使用时,slidingExpiration似乎不起作用

标签 javascript c# asp.net angularjs iis

我的用户在SPA页面上,几个小时后就注销了。但是,如果他们使用较旧的回发表单,则它们永远不会超时。因此,您有了上下文,我在底部包含了足够的代码来为问题的描述提供上下文。

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,以在后台针对表单对象触发,只是诱使浏览器生成适当的表单回发。我想避免这样做,因为它似乎很hacky。

我发现的唯一另一个关键问题是,我看到大量schannel错误被记录到IIS服务器上的应用程序事件日志中。它们都是10,10,没有充分的记录。 10系列在10,10之外有充分的文档记录。但是这些建议似乎都不起作用,甚至都不相关。

服务器是IIS 7.5,我已经在IIS 8上尝试过。

应用程序日志错误:


生成致命警报并将其发送到远程端点。这可能会导致连接终止。 TLS协议定义的致命错误代码是10。WindowsSChannel错误状态是10。

错误状态:10,警报描述:10

生成致命警报并将其发送到远程端点。这可能会导致连接终止。 TLS协议定义的致命错误代码为40。WindowsSChannel错误状态为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日志之后,我仍然看到所有内容都已取消身份验证。


Windows上的FF-失败
Windows上的Chrome-失败
Chrome on Droid-失败
iPad上的Safari浏览器-失败
Windows上的IE-失败


12/10发现

我发现了真正的问题。 MVC控制器中的身份验证与Web API控制器不兼容。因此,当我使用MVC控制器进行身份验证时,Web API控制器基本上会忽略它,最终导致身份验证超时。

最新发现

显然,当asp.net worker进程关闭并重新启动时,它将得到一个错误的标志,即数据库模式不存在。因此,我删除了检查,所有读取和写入都开始正常工作。有趣的是,当mvc控制器验证失败时,api控制器将伪造一个新的cookie。就像在创建一个新的提供者实例一样。但是,我找不到第二个实例,因此我必须假定现有的提供程序已被复制。

修复正在测试的问题

现在,我已经删除了数据库测试,现在我将在长期测试中测试该问题。每次长时间运行的时间都比工作进程的存活时间长,但比会话超时时间短。

发现此错误的基石

显然,IIS Express隐藏了该错误,因为它似乎没有外部工作进程即可运行。因此,我将测试环境移到了本地IIS服务器上。

最佳答案

似乎有几个问题导致了我的问题,每个问题都在这里分解:


IIS Express没有像完整的IIS那样关闭会话。

因此,我将应用程序移到了本地IIS,并添加了所有日志记录。

每次调用API控制器时,ASP.NET工作进程都会启动新的提供程序实例。

这将导致每个调用进行新的架构检查。 MVC控制器在每次初次启动时只会引起一次检查。
由于我的提供程序已嫁接到我的应用程序架构,因此我仅禁用了架构检查。

必须告知Angular将Cookie封送。

所以我加了:cfg: { withCredentials: true, responseType: "json" }
响应类型是为了覆盖偶尔出现的“文字/文字”问题。现在我总是看到'application / json'。这似乎是一个浏览器问题,主要与IE有关。

我还必须在我的WebApiConfig类的register方法中添加config.MapHttpAttributeRoutes();


使用所有这些,我发现问题的核心是每个api调用都导致我的安全提供程序重新测试该架构,我的MVC控制器设置为在首次加载后禁止该测试。测试总是失败,因为我必须扩展几个表,但是我不需要更改模型。

解决方法:我从提供程序中删除了该测试。由于提供者与应用程序的其余部分紧密联系在一起,因此将其视为典型的ASP.NET成员资格提供者似乎并不合逻辑。这是我不需要的最重要功能。

第二个好处是,我获得了一些性能提升。

关于javascript - 与SPA一起使用时,与ASP.NET MVC API一起使用时,slidingExpiration似乎不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26412773/

相关文章:

javascript - 将外部 JS/CSS 添加到 Magento 网站

javascript - 为单个输入字段设置 ng-model 和 ng-value

javascript - 诺基亚/HERE map 在 map.zoomTo 之后返回到 0 级缩放

asp.net - 哪些工具适合设计 ASP.NET 用户界面以显示给客户端?

javascript - 如何读取json并在html中显示

c# - 仅在特定日期和时间解雇一次工作

c# - 加载没有文化和版本的程序集

C# 使用 Nancy 获取 HTTP 正文

asp.net - "asp.net"是什么意思?

C#.NET 如何使用表单例份验证将 session 超时设置为 6 小时?