MVC 5 OWINログインのクレームを学習しようとしています。できるだけシンプルにしようと思いました。 MVCテンプレートから始めて、クレームコードを挿入しました(以下を参照)。ビューで@ Html.AntiForgeryToken()ヘルパーを使用するとエラーが発生します。
エラー:
A claim of type 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier' or
'http://schemas.Microsoft.com/accesscontrolservice/2010/07/claims/identityprovid
er' was not present on the provided ClaimsIdentity.
To enable anti-forgery token support with claims-based authentication, please verify that
the configured claims provider is providing both of these claims on the ClaimsIdentity
instances it generates. If the configured claims provider instead uses a different claim
type as a unique identifier, it can be configured by setting the static property
AntiForgeryConfig.UniqueClaimTypeIdentifier.
Exception Details: System.InvalidOperationException: A claim of type
'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier' or
'http://schemas.Microsoft.com/accesscontrolservice/2010/07/claims/identityprovider' was
not present on the provided ClaimsIdentity. To enable anti-forgery token
support with claims-based authentication, please verify that the configured claims provider
is providing both of these claims on the ClaimsIdentity instances it generates.
If the configured claims provider instead uses a different claim type as a unique
identifier, it can be configured by setting the static property
AntiForgeryConfig.UniqueClaimTypeIdentifier.
Source Error:
Line 4: using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new
{ id = "logoutForm", @class = "navbar-right" }))
Line 5: {
Line 6: @Html.AntiForgeryToken()
POSTログインアクション
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, "Brock"),
new Claim(ClaimTypes.Email, "[email protected]")
};
var id = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);
var ctx = Request.GetOwinContext();
var authenticationManager = ctx.Authentication;
authenticationManager.SignIn(id);
return RedirectToAction("Welcome");
}
_ LoginPartial.cshtml
@using Microsoft.AspNet.Identity
@if (Request.IsAuthenticated)
{
using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" }))
{
@Html.AntiForgeryToken()
<ul class="nav navbar-nav navbar-right">
<li>
@Html.ActionLink("Hello " + User.Identity.GetUserName() + "!", "Index", "Manage", routeValues: null, htmlAttributes: new { title = "Manage" })
</li>
<li><a href="javascript:document.getElementById('logoutForm').submit()">Log off</a></li>
</ul>
}
}
設定してみましたClaimTypes.NameIdentifier
( このようにSO答え )
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
}
そして、私は「ただ?」このエラーを取得
A claim of type 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier' was
not present on the provided ClaimsIdentity.
AntiforgeryTokenは、クロスサイトスクリプティングの防止に役立つため、残しておきたいと思います。
申し立てIDにClaimTypes.NameIdentifier
がありません。申し立て配列にさらに追加する必要があります:
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, "username"),
new Claim(ClaimTypes.Email, "[email protected]"),
new Claim(ClaimTypes.NameIdentifier, "userId"), //should be userid
};
より修正するために情報をClaimにマップするには:
ClaimTypes.Name => map to username
ClaimTypes.NameIdentifier => map to user_id
ユーザー名も一意であるため、偽造防止トークンのサポートにusername
を使用できます。
Application_Start()
で、Claim
として使用するNameIdentifier
を指定します。
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
...
System.Web.Helpers.AntiForgeryConfig.UniqueClaimTypeIdentifier =
System.Security.Claims.ClaimTypes.NameIdentifier;
...
}
}
参照: http://brockallen.com/2012/07/08/mvc-4-antiforgerytoken-and-claims/
AntiForgeryConfig
これを解決する1つの方法は、AntiForgeryConfigを設定して他のClaimTypeを使用することです。
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Email;
}
NameIdentifierおよびIdentityProvider ClaimTypesを追加します
または、NameIdentifierおよびIdentityProvider ClaimTypesをクレームに追加することもできます。
List<Claim> _claims = new List<Claim>();
_claims.AddRange(new List<Claim>
{
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", _user.Email)),
new Claim("http://schemas.Microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", _user.Email)
})
これをGlobal.asax.cs Application_Start()で使用して、エラーを解決しました:
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Name;
これと同様の問題があり、Cookieに関連していることが判明しました。私は2つのMVCサイトを同時に開発していました。ASP.Netサイトはすべてデフォルトで同じCookie名を使用しているため、2つのサイトは互いに干渉していました。 Cookieをクリアすると問題が解決しました。これについては ここに答える にもっとあります。
Global.asax.csファイルは次のようになります。
namespace YOUR_PROJECT_NAME
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
}
}
}
意味それがthtaと異なる場合は、このコードをそれに追加する必要があります。
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
「YOUR_PROJECT_NAME」を自分のものに変更することを忘れないでください。