防伪标志问题

我对防伪标志有意见 我已经创建了我自己的用户类工作得很好,但现在我得到了一个错误,每当我去 户口/登记册页面。错误是:

类型的要求 Http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier 或者 Http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider 为了防止伪造,在提供的声明身份中没有显示 令牌支持声明为基础的认证,请验证 已配置的索赔提供程序在 如果配置的声明 提供者使用不同的声称类型作为唯一标识符, 它可以通过设置 static 属性进行配置 唯一声明类型标识符。

我发现了这篇文章:

Http://stack247.wordpress.com/2013/02/22/antiforgerytoken-a-claim-of-type-nameidentifier-or-identityprovider-was-not-present-on-provided-claimsidentity/

所以我把 应用程序 _ 开始方法改成了这样:

protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();


FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);


AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Email;
}

但是当我这样做的时候,我得到了这个错误:

类型的要求 Http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress 没有出现在所提供的声明身份中。

以前有人遇到过这个问题吗? 如果有,你知道怎么解决吗?


下面是我的自定义用户类:

public class Profile : User, IProfile
{
public Profile()
: base()
{
this.LastLoginDate = DateTime.UtcNow;
this.DateCreated = DateTime.UtcNow;
}


public Profile(string userName)
: base(userName)
{
this.CreatedBy = this.Id;


this.LastLoginDate = DateTime.UtcNow;
this.DateCreated = DateTime.UtcNow;


this.IsApproved = true;
}
    

[NotMapped]
public HttpPostedFileBase File { get; set; }


[Required]
public string CompanyId { get; set; }


[Required]
public string CreatedBy { get; set; }
public string ModifiedBy { get; set; }


public DateTime DateCreated { get; set; }
public DateTime? DateModified { get; set; }
public DateTime LastLoginDate { get; set; }


[Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredTitle")]
public string Title { get; set; }
[Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredFirstName")]
public string Forename { get; set; }
[Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredLastName")]
public string Surname { get; set; }


[Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredEmail")]
public string Email { get; set; }
public string JobTitle { get; set; }
public string Telephone { get; set; }
public string Mobile { get; set; }
public string Photo { get; set; }
public string LinkedIn { get; set; }
public string Twitter { get; set; }
public string Facebook { get; set; }
public string Google { get; set; }
public string Bio { get; set; }


public string CompanyName { get; set; }


[Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredCredentialId")]
public string CredentialId { get; set; }
[Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredSecurityCode")]
public bool IsLockedOut { get; set; }
public bool IsApproved { get; set; }


[Display(Name = "Can only edit own assets")]
public bool CanEditOwn { get; set; }
[Display(Name = "Can edit assets")]
public bool CanEdit { get; set; }
[Display(Name = "Can download assets")]
public bool CanDownload { get; set; }
[Display(Name = "Require approval to upload assets")]
public bool RequiresApproval { get; set; }
[Display(Name = "Can approve assets")]
public bool CanApprove { get; set; }
[Display(Name = "Can synchronise assets")]
public bool CanSync { get; set; }


public bool AgreedTerms { get; set; }
public bool Deleted { get; set; }
}


public class ProfileContext : IdentityStoreContext
{
public ProfileContext(DbContext db)
: base(db)
{
this.Users = new UserStore<Profile>(this.DbContext);
}
}


public class ProfileDbContext : IdentityDbContext<Profile, UserClaim, UserSecret, UserLogin, Role, UserRole>
{
}

我的配置文件对于我的存储库来说很简单,看起来像这样:

public interface IProfile
{
string Id { get; set; }
string CompanyId { get; set; }
    

string UserName { get; set; }
string Email { get; set; }


string CredentialId { get; set; }
}

用户类是 微软。 AspNet.Identity。 EntityFramework。用户类。 我的 财务总监是这样的:

[Authorize]
public class AccountController : Controller
{
public IdentityStoreManager IdentityStore { get; private set; }
public IdentityAuthenticationManager AuthenticationManager { get; private set; }
    

public AccountController()
{
this.IdentityStore = new IdentityStoreManager(new ProfileContext(new ProfileDbContext()));
this.AuthenticationManager = new IdentityAuthenticationManager(this.IdentityStore);
}


//
// GET: /Account/Register
[AllowAnonymous]
public ActionResult Register()
{
return View();
}


//
// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
try
{
// Create a profile, password, and link the local login before signing in the user
var companyId = Guid.NewGuid().ToString();
var user = new Profile(model.UserName)
{
CompanyId = companyId,
Title = model.Title,
Forename = model.Forename,
Surname = model.Surname,
Email = model.Email,
CompanyName = model.CompanyName,
CredentialId = model.CredentialId
};


if (await IdentityStore.CreateLocalUser(user, model.Password))
{
//Create our company
var company = new Skipstone.Web.Models.Company()
{
Id = companyId,
CreatedBy = user.Id,
ModifiedBy = user.Id,
Name = model.CompanyName
};


using (var service = new CompanyService())
{
service.Save(company);
}


await AuthenticationManager.SignIn(HttpContext, user.Id, isPersistent: false);
return RedirectToAction("Setup", new { id = companyId });
}
else
{
ModelState.AddModelError("", "Failed to register user name: " + model.UserName);
}
}
catch (IdentityException e)
{
ModelState.AddModelError("", e.Message);
}
}


// If we got this far, something failed, redisplay form
return View(model);
}


//
// POST: /Account/Setup
public ActionResult Setup(string id)
{
var userId = User.Identity.GetUserId();
using (var service = new CompanyService())
{
var company = service.Get(id);
var profile = new Profile()
{
Id = userId,
CompanyId = id
};


service.Setup(profile);


return View(company);
}
}
}

它过去常常使用 [ ValidateAntiForgeryToken ]属性进行装饰,但这就是它停止工作的地方。

为什么?

83189 次浏览

尝试设置(在 global.cs 中) :

AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;

你知道在你的声明身份中你会得到什么声明吗? 如果不知道:

  1. 删除 [ValidateAntiForgeryToken]属性
  2. 在控制器中的某个地方放置一个断点,并对其进行中断
  3. 然后查看当前的 ClaimsIdentity并检查索赔
  4. 找到一个您认为能够唯一识别您的用户的方法
  5. AntiForgeryConfig.UniqueClaimTypeIdentifier设置为该索赔类型
  6. 恢复 [ValidateAntiForgeryToken]属性

尝试在匿名窗口中打开链接或清除该域的 cookie (即 localhost)。

编辑: 现在对这个问题有了更深刻的理解,你可以忽略我下面的回答。

在 Global.asax.cs 的 Application _ Start ()中设置 AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;为我修复了它。尽管我已经有了声明 http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier集,但是我得到了与原始问题中相同的错误。但是如上所述指出这一点是有效的。



从 Mvc4开始,防伪令牌不使用 ABc0作为唯一标识符。相反,它查找错误消息中给出的两个声明。

更新注意: 这不应该是必需的 您可以在用户登录时将丢失的声明添加到您的声明标识中,如下所示:

string userId = TODO;
var identity = System.Web.HttpContext.Current.User.Identity as ClaimsIdentity;
identity.AddClaim(new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", userId));
identity.AddClaim(new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", userId));

请注意,其中一个声明可能已经存在,如果同时添加这两个声明,则会得到一个重复声明的错误。如果是这样,只需添加一个缺失。

把这个输入 global.asax.cs

AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimsIdentity.DefaultNameClaimType;

在 Global.asax.cs 中,

1. 添加这些名称空间

using System.Web.Helpers;
using System.Security.Claims;

在 Application _ Start 方法中添加这一行:

 protected void Application_Start()
{
.......
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimsIdentity.DefaultNameClaimType;
}

独立声明类型标识符 = 声明类型

工程为我的情况下,我使用 ADFS 身份验证。