嗨,我已经浏览了很多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,这可能就是前进的方向。