asp.net-mvc MVC 5 OWIN 使用声明和 AntiforgeryToken 登录。我是否错过了 ClaimsIdentity 提供商?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30976980/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MVC 5 OWIN login with claims and AntiforgeryToken. Do I miss a ClaimsIdentity provider?
提问by radbyx
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.
我正在尝试学习 MVC 5 OWIN 登录的声明。我尽量保持简单。我从 MVC 模板开始并插入了我的声明代码(见下文)。在视图中使用 @Html.AntiForgeryToken() 帮助程序时出现错误。
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 登录操作
// 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
_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)
我已经尝试过设置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;
}
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.
我想保留 antiforgeryToken 因为它可以帮助防止跨站点脚本。
回答by Travis Russi
In your Application_Start(), specify which Claimto use as the NameIdentifier:
在您的 中Application_Start(),指定Claim要用作的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/
参见:http: //brockallen.com/2012/07/08/mvc-4-antiforgerytoken-and-claims/
回答by cuongle
Your claim identity does not have ClaimTypes.NameIdentifier, you should add more into claim array:
您的声明标识没有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
};
To map the information to Claim for more corrective:
将信息映射到 Claim 以进行更正:
ClaimTypes.Name => map to username
ClaimTypes.NameIdentifier => map to user_id
Since username is unique also, so you are able to use usernamefor anti-forgery token support.
由于用户名也是唯一的,因此您可以username用于防伪令牌支持。
回答by Alexandre N.
AntiForgeryConfig
防伪配置
One way to solve it is to set AntiForgeryConfig to use other ClaimType.
一种解决方法是将 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;
}
Add NameIdentifier and IdentityProvider ClaimTypes
添加 NameIdentifier 和 IdentityProvider ClaimTypes
Alternatively, you can add NameIdentifier and IdentityProvider ClaimTypes to your claims.
或者,您可以将 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)
})
请参阅:https: //stack247.wordpress.com/2013/02/22/antiforgerytoken-a-claim-of-type-nameidentifier-or-identityprovider-was-not-present-on-provided-claimsidentity/
回答by Carlos Escobosa
I used this on Global.asax.cs Application_Start() and solved the error:
我在 Global.asax.cs Application_Start() 上使用了它并解决了错误:
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Name;
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Name;
回答by tomRedox
I had a similar issue to this that turned out to be cookie related; I was developing two MVC sites simultaneously and because ASP.Net sites all use the same cookie name by default the two sites were interfering with each other. Clearing the cookies fixed the issue. There's more on this in my answer here.
我有一个与此类似的问题,结果证明与 cookie 相关;我正在同时开发两个 MVC 站点,因为默认情况下 ASP.Net 站点都使用相同的 cookie 名称,这两个站点相互干扰。清除 cookie 解决了该问题。我的回答中有更多关于此的内容。
回答by Yilmazam
Your Global.asax.cs file should be like this:
您的 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;
}
}
}
Means If its not like thta, You have to add this code to that:
意思是如果它不像 thta,你必须添加这个代码:
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
and Don't forget yo change "YOUR_PROJECT_NAME" with yours.
并且不要忘记将“YOUR_PROJECT_NAME”更改为您的。

