MVC 5 OWIN login with claims and AntiforgeryToken. Do I miss a ClaimsIdentity provider?
Solution 1
Your claim identity does not have ClaimTypes.NameIdentifier
, you should add more into claim array:
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, "username"),
new Claim(ClaimTypes.Email, "[email protected]"),
new Claim(ClaimTypes.NameIdentifier, "userId"), //should be userid
};
To map the information to Claim for more corrective:
ClaimTypes.Name => map to username
ClaimTypes.NameIdentifier => map to user_id
Since username is unique also, so you are able to use username
for anti-forgery token support.
Solution 2
In your Application_Start()
, specify which Claim
to use as the NameIdentifier
:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
...
System.Web.Helpers.AntiForgeryConfig.UniqueClaimTypeIdentifier =
System.Security.Claims.ClaimTypes.NameIdentifier;
...
}
}
See: http://brockallen.com/2012/07/08/mvc-4-antiforgerytoken-and-claims/
Solution 3
AntiForgeryConfig
One way to solve it is to set AntiForgeryConfig to use other 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;
}
Add NameIdentifier and IdentityProvider ClaimTypes
Alternatively, you can add NameIdentifier and IdentityProvider ClaimTypes to your claims.
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)
})
Solution 4
I used this on Global.asax.cs Application_Start() and solved the error:
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Name;
Solution 5
Your Global.asax.cs file should be like this:
namespace YOUR_PROJECT_NAME
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
}
}
}
Means If its not like thta, You have to add this code to that:
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
and Don't forget yo change "YOUR_PROJECT_NAME" with yours.
Related videos on Youtube
radbyx
Backend developer at al dente. Former WebDeveloper at CapaSystems. I like to code in C#, MVC, JavaScript, Jquery, winforms, MSSQL, MySql ect. :) email: radbyx AT gmail DOT com
Updated on July 09, 2022Comments
-
radbyx almost 2 years
I'm trying to learn Claims for MVC 5 OWIN login. I try'ed to keep it as simple as possible. I started with the MVC template and inserted my claims code (see below). I get an error when I use the @Html.AntiForgeryToken() helper in the View.
Error:
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 Login action
// 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> } }
I have tryed setting
ClaimTypes.NameIdentifier
(like in this SO answer)protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier; }
And then I "only?" get this error
A claim of type 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier' was not present on the provided ClaimsIdentity.
I want to keep the antiforgeryToken because it can help against cross-site scripting.
-
radbyx almost 9 yearsI don't know what the mapping does. First I inserted the
NameIdentifier
too but got the same error. Then I tryed adding in Global.asax.cs without knowing what it does, but now it works. Maybe it's the same as your mapping? Global.asax.cs.: AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Name; AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Email; AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier; -
OpTech Marketing about 6 yearsThanks Travis, this fixed my issue right away.... Experienced it when applying Auto 0 to OWIN Asp.net
-
Manfred about 6 yearsThe error message in the question mentions
identityprovider
which doesn't exist as a constant inClaimTypes
in ASP.NET MVC 4.6.1. Therefore it appears as if @travis-russi seems to fit better. In this answernew Claim(ClaimTypes.NameIdentifier, "userId')
would suffice sinceAntiForgeryConfig.UniqueClaimTypeIdentifier
is set toClaimTypes.NameIdentifier
.