前一篇关于anti-forgery token问题的博文提到我们可以通过修改AntiForgeryConfig.UniqueClaimTypeIdentifier属性来避免AntiForgeryToken生成的问题。但是也许你编译运行后又得到了这样一个错误:
A claim of type 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier' was not present on the provided ClaimsIdentity.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: A claim of type 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier' was not present on the provided ClaimsIdentity.
Source Error:Line 4: using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" }))
Line 5: {
Line 6: @Html.AntiForgeryToken()
Line 7:
Line 8: <ul class="nav navbar-nav navbar-right">
这说明做身份验证的STS (比如 ADFS)没有提供NameIdentifier的信息。以ADFS为例,什么是NameIdentifier,看图
NameIdentifier在ADFS中就是“Name ID”。这是我的ADFS上配置的一条”Claims Rule“,将Active Directory用户的E-mail地址映射为Claim Based Identity中的Name ID。这里要注意,图中左边的LDAP Attribute必须要有值,否则即使我们配置了一条映射,在用户登陆后ADFS发出的Claims中也没有我们要的数据,比如本例中的Name ID。
如何确定LDAP Attribute也没有值?打开Active Directory的用户属性界面,确认我们需要的属性(比如E-mail)不为空。
如果不清楚后端的STS到底提供了哪些可用的Claims Types,可以在页面添加如下的代码来显示当前所有拿到的身份验证的信息
@if (Request.IsAuthenticated)
{
<ul>
@foreach (var claim in ((System.Security.Claims.ClaimsIdentity)User.Identity).Claims)
{
<li>Issuer:@claim.Issuer OriginalIssuer:@claim.OriginalIssuer Value:@claim.Value</li>
}
</ul>
}