我正在尝试在现有的Web应用程序中实现AntiForgeryToken,该应用程序是具有AngularJS前端的ASP.Net MVC 5应用程序。
以下是我的BaseFilter的代码:
public class BaseFilter : ActionFilterAttribute
{
private const string CLAIM_TYPE_EMAILADDRESS =
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress";
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
Debug.WriteLine("Base filter started at ={0}", DateTime.Now.ToString());
var baseController = filterContext.Controller as BaseController;
var routeData = filterContext.RouteData;
var controller = routeData.Values["controller"].ToString();
var action = routeData.Values["action"].ToString();
if (baseController != null)
{
var claims1 = ClaimsPrincipal.Current.Identities.First();
var emailId1 = claims1.Claims.FirstOrDefault(x => x.Type == CLAIM_TYPE_EMAILADDRESS).Value;
var roleName=claims1.Claims.FirstOrDefault(x => x.Type == "Role").Value;
baseController.GetCurrentUser();
if (roleName == "Freemium")
{
baseController.GetFreemiumDaysLeft(emailId1);
}
}
//Calls should be made only in case of Page Request instead of Ajax Request
if (!filterContext.HttpContext.Request.IsAjaxRequest())
{
if (filterContext.HttpContext.Request.QueryString["contractId"] != null)
{
var contractId =
Convert.ToInt32(new EncryptDecrypt().DecryptString(filterContext.HttpContext.Request.QueryString["contractId"]));
if (baseController != null)
{
baseController.GetContractProgressStatus(contractId, controller, filterContext);
}
}
else
{
if (
controller != "Dashboard" &&
controller != "UserRegistration" &&
controller != "Help" &&
controller != "BasicInfo" && action == "Index")
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{"controller", "BasicInfo"},
{"action", "Index"}
});
}
}
//if(controller)
string cookieToken = "";
string formToken = "";
if (filterContext.HttpContext.Request.HttpMethod != "GET")
{
var tokenHeaders = filterContext.HttpContext.Request.Headers.GetValues("RequestVerificationToken").FirstOrDefault();
if (tokenHeaders != null)
{
string[] tokens = tokenHeaders.Split(':');
if (tokens.Length == 2)
{
cookieToken = tokens[0].Trim();
formToken = tokens[1].Trim();
}
}
System.Web.Helpers.AntiForgery.Validate(cookieToken, formToken);
}
base.OnActionExecuting(filterContext);
}
}
以下是AntiForgery扩展名:
public static class AntiForgeryExtension
{
public static string RequestVerificationToken(this HtmlHelper helper)
{
return String.Format("__RequestVerificationToken={0}", GetTokenHeaderValue());
}
private static string GetTokenHeaderValue()
{
string cookieToken, formToken;
System.Web.Helpers.AntiForgery.GetTokens(null, out cookieToken, out formToken);
return cookieToken + ":" + formToken;
}
}
以下是我的Index.cshtml:
@using MyProj.Web.AuthData
<script src="~/Scripts/DashboardVersion.js"></script>
<!-- Page header -->
<div class="page-header page-header-ey-default title-height">
<div class="page-header-content">
<div class="page-title">
</div>
</div>
</div>
<!-- /page header -->
<section>
<div>
<div class="clear1"></div>
<div ng-app="dashboardVersion" ng-controller="DashboardController" ng-cloak data-ng-init="antiForgeryToken='@Html.RequestVerificationToken()'">
</div>
</div>
</section>
以下是index.js的帖子调用:
$scope.saveVersion = function () {
if ($scope.SaveVersion.VersionName === undefined || $scope.SaveVersion.VersionName.toString().trim() === "") {
showWarning("Please enter scenario name.");
return;
}
else if (_.find($scope.VersionsLowercase,
{ VersionName: $scope.SaveVersion.VersionName.toString().toLowerCase().trim() })) {
showWarning("Version with similar name already exists.");
}
else {
var token = $scope.antiForgeryToken;
var headers = {
headers: {
'RequestVerificationToken': token
}};
$scope.SaveVersion.VersionName = $scope.SaveVersion.VersionName.toString().trim();
$http.post("/PortfolioVersion/SaveVersion/", $scope.SaveVersion, headers).then(function (response) {
clearDirty();
$("#version-modal").modal("hide");
if (response.data == "true") {
showSuccess("data successfully saved.");
}
else if (response.data == "false") {
showError("An error occured while saving .");
}
$scope.init();
});
}
};
以下代码已添加到Global.asax:
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
我已经从机器中的IIS手动生成了机器密钥,并将其添加到Web.config中的...:
<machineKey
validationKey="myKey"
decryptionKey="myKey"
validation="SHA1"
decryption="AES"
/>
添加所有这些内容后,我在TokenValidation中收到以下错误:
Message =防伪令牌无法解密。如果此应用程序由Web场或群集托管,请确保所有计算机都运行相同版本的ASP.NET网页,并且确保配置指定了显式加密和验证密钥。自动生成不能在群集中使用。
我已遵循以下链接中给出的所有答案: The anti-forgery token could not be decrypted
但是似乎没有什么对我有用。请帮助解决我的问题。