chrome和IE上集成Windows身份验证的行为不一致

时间:2019-03-14 14:25:44

标签: javascript asp.net-web-api2 windows-authentication

我面临一个奇怪的问题,涉及SPA网站(内联网)上的集成Windows身份验证

登录流程如下:

  • 客户导航到SPA网站
  • 在SPA初始化期间,SPA从我的WEB API向令牌端点发送请求,在那里我提取AD凭据,进行数据库查找并添加一些角色声明
  • 令牌端点返回一个令牌,该令牌有效期为几个小时
  • SPA在所有后续的http请求中使用令牌
  • 当令牌即将到期(提前10秒)时,SPA再次发出完全相同的令牌请求,该请求到达我的OAuthAuthorizationServerProvider代码,,但有时context.OwinContext.Request.User.Identity为null ,通过AD凭据出现问题
  • 最终用户现在已经没有有效的令牌,并且无法进行任何http调用,刷新页面可解决此问题,发出完全相同的令牌请求并每次都能正常工作

一些评论:

  • 此问题同时存在于IE和chrome中,但IE的搭接趋向于减少
  • Web服务器是IIS 7.5,仅启用Windows身份验证,仅NTLM作为提供程序

客户端(我将fetch用作其他所有内容,我将其改写为经典方法以消除可能的干扰,无济于事):

public async logIn(): Promise<boolean> {
    return new Promise(function (resolve, reject) {

        var http = new XMLHttpRequest();
        var url = `${environment.baseUrl}/token`;
        var params = 'grant_type=password&username=&password=';
        http.open('POST', url, true);
        http.withCredentials = true;

        //Send the proper header information along with the request
        http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

        http.onreadystatechange = () => {
            if (http.readyState == 4 && http.status == 200) {
                let result = JSON.parse(http.responseText);
                alert(http.responseText);

                if (result.access_token) {
                    localStorage.setItem(EMPLOYEEID, result.employeeId);
                    localStorage.setItem(ROLES, result.roles);
                    localStorage.setItem(TOKEN, result.access_token);
                    localStorage.setItem(
                        TOKENEXPIRY,
                        moment()
                            .add(result.expires_in, "seconds")
                            .toJSON()
                    );
                    return resolve(true);
                } else return resolve(false);
            }
        }
        http.send(params);
    })
}

public enableSilentTokenRenew() {
    setTimeout(async () => {
        await this.logIn(); //this fails
        this.enableSilentTokenRenew();
    }, moment(localStorage.getItem(TOKENEXPIRY)).diff(moment(), "millisecond") - 10000);
}

服务器:

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        var adUser = context.OwinContext.Request.User.Identity // this is null the second time

0 个答案:

没有答案