所提供的防伪令牌用于用户“ xxx”,但当前用户是“”

时间:2018-09-28 20:04:38

标签: c# jquery asp.net-mvc

嗨,我已经浏览了很多S.O。关于这个主题的页面,但是我的有点不同。这与防伪保护的登录页面或用户单击“后退”按钮无关。在我们的大学中,我们使用密歇根大学的CoSign作为单点登录解决方案。用户通过共同签名进行身份验证,成功后,用户名由IIS服务器在Request.ServerVariables [“ REMOTE_USER”]中提供,然后可用于授权等。

下面是一些代码:global.asax.cs中的

Session["username"] = Request.ServerVariables["REMOTE_USER"];

在可能使用Ajax的每个页面上(在文件Init.js中;来自https://blog.alexmaccaw.com/jswebapps-csrf的代码):

$(document).ready(function () {
    SetCSRFHeader();
}
function SetCSRFHeader() {
var CSRF_HEADER = 'RequestVerificationToken';

var setCSRFToken = function (securityToken) {
    jQuery.ajaxPrefilter(function (options, _, xhr) {
        if (!xhr.crossDomain)
            xhr.setRequestHeader(CSRF_HEADER, securityToken);
    });
};
var theTokenVal = $('#__bothTokens').val();
setCSRFToken(theTokenVal);
}

在_Layout.cshtml中:

@Html.AntiForgeryToken()
@{
string cookieToken, formToken, bothTokens;
AntiForgery.GetTokens(null, out cookieToken, out formToken);
bothTokens = cookieToken + ":" + formToken;
}
<input type="hidden" id="__bothTokens" value="@(bothTokens)" />

我还编写了一个实现IHttpModule的类,以检查所有POST请求以查找包含的标头,对其进行解析并进行验证(来自https://security.stackexchange.com/questions/91164/how-to-check-the-origin-header-server-wide-in-iis-to-prevent-csrf的代码):

public class HeaderCheck : IHttpModule
{
     public HeaderCheck()
    {
    }

    public void Init(HttpApplication application)
    {
        application.BeginRequest +=
            (new EventHandler(this.Application_BeginRequest));
    }

    private void Application_BeginRequest(Object source,
         EventArgs e)
    {
        HttpApplication application = (HttpApplication)source;
        HttpContext context = application.Context;
        int errCode = 0;
        int STATCODE = 403;
        string cookieToken = "";
        string formToken = "";
        if (context.Request.HttpMethod == "POST") // only on POST requests
        {
            if (context.Request.Headers["Content-Type"] != null) 
            {
                if (context.Request.Headers["Content-Type"] == "application/json;") // JSON check
                {
                    if (context.Request.Headers["RequestVerificationToken"] != null)
                    {
                        string tokenHeaders = context.Request.Headers["RequestVerificationToken"]; 
                        string[] tokens = tokenHeaders.Split(':');
                        if (tokens.Length == 2)
                        {
                            cookieToken = tokens[0].Trim();
                            formToken = tokens[1].Trim();
                        }
                    }
                    else
                    {
                        errCode = 3;
                    }
                }
                else if (context.Request.Headers["Content-Type"].Length >= 19)
                {
                    if (context.Request.Headers["Content-Type"].Substring(0, 19) == "multipart/form-data") // Form check
                    {
                        HttpCookie cookie = new HttpCookie("__RequestVerificationToken");
                        cookie = context.Request.Cookies["__RequestVerificationToken"];
                        formToken = context.Request.Form["__RequestVerificationToken"];
                        if (formToken == null) { tokenstr = "form null"; }
                        if (cookie != null)
                        {
                            cookieToken = cookie.Value;
                            System.Web.Helpers.AntiForgery.Validate(cookieToken, formToken);
                        }
                        else // cookie is null
                        {
                            errCode = 4;
                        }
                    }
                }
                else // neither acceptable content form
                {
                    errCode = 5;
                }
            }
            else // content type should not be null
            {
                errCode = 6;
            }
            if (errCode > 0)
            {
                try
                {
                    System.Web.Helpers.AntiForgery.Validate(cookieToken, formToken);
                }
                catch (HttpAntiForgeryException e2)
                {
                    string err = @"Antiforgery tokens not validated" +
                        "<br><b>Error in: </b>"
                        + context.Request.Url.ToString()
                        + "<br><b>Error Message: </b>"
                        + e2.Message.ToString()
                        + "<br><b>Stack Trace:</b><br>"
                        + e2.StackTrace.ToString();
                    EmailContext.sendEmailOnError(err); // sends email to me for debugging
                }
            }

            if (errCode > 0)
            {
                context.Response.StatusCode = STATCODE;
                context.Response.Flush();
                context.Response.End();
            }
        }
    }

    public void Dispose() { }

}
}

我的问题:为什么我在此问题的标题中出现错误? AntiForgeryValidate如何知道该令牌是给我的,但是以某种方式生成的令牌是给当前用户“”的?有什么办法可以将用户放入令牌中?我什至尝试过Reload AntiForgeryToken after a login上的建议,以便始终在用户第一次访问首页时重新生成令牌(因为他们当时已经登录。这与在Visual Studio中进行开发有关吗?在HTTP中,但是受共签名保护的接受环境是https?这与为IIS进行匿名身份验证配置有关吗(我认为它必须在共签名下运行)。

谢谢您的建议。

编辑:我越来越认为这是由于IIS匿名身份验证是唯一启用的模式。但是任何其他方式都需要某种第二次登录,并且由于cosign是THE身份验证提供程序,所以没有帮助。因此,如果有人有任何想法如何以编程方式将从cosign接收的用户凭据插入IIS,这可能就是前进的方向。

0 个答案:

没有答案