首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MVC5owin使用claims和AntiforgeryToken登录。我会想念ClaimsIdentity提供者吗?

MVC5owin使用claims和AntiforgeryToken登录。我会想念ClaimsIdentity提供者吗?
EN

Stack Overflow用户
提问于 2015-06-22 09:54:40
回答 6查看 26.3K关注 0票数 17

我正在尝试学习MVC 5 OWIN登录的声明。我试着尽量保持简单。我从MVC模板开始,并插入了索赔代码(见下文)。当我在视图中使用@Html.AntiForgeryToken()助手时,会得到一个错误。

错误:

代码语言:javascript
复制
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登录操作

代码语言:javascript
复制
// 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, "brockallen@gmail.com")
    };
    var id = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);

    var ctx = Request.GetOwinContext();
    var authenticationManager = ctx.Authentication;
    authenticationManager.SignIn(id);

    return RedirectToAction("Welcome");
}

_LoginPartial.cshtml

代码语言:javascript
复制
@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 (like in this SO answer)

代码语言:javascript
复制
protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);

    AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
}

然后我就“只?”得到这个错误

代码语言:javascript
复制
A claim of type 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier' was 
not present on the provided ClaimsIdentity.

我想保留antiforgeryToken,因为它可以帮助防止跨站点脚本编写。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2015-06-22 10:05:29

您的索赔标识没有ClaimTypes.NameIdentifier,您应该在索赔数组中添加更多内容:

代码语言:javascript
复制
var claims = new List<Claim>
{
    new Claim(ClaimTypes.Name, "username"),
    new Claim(ClaimTypes.Email, "user@gmail.com"),
    new Claim(ClaimTypes.NameIdentifier, "userId"), //should be userid
};

若要绘制要要求进行更多纠正的信息:

代码语言:javascript
复制
ClaimTypes.Name => map to username
ClaimTypes.NameIdentifier => map to user_id

因为用户名也是唯一的,所以您可以使用username来支持防伪造令牌。

票数 16
EN

Stack Overflow用户

发布于 2015-09-28 23:14:18

Application_Start()中,指定要使用哪个Claim作为NameIdentifier

代码语言:javascript
复制
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/

票数 18
EN

Stack Overflow用户

发布于 2016-02-21 00:39:24

AntiForgeryConfig

解决这个问题的一种方法是将AntiForgeryConfig设置为使用其他ClaimType。

代码语言:javascript
复制
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和IdentityProvider ClaimTypes

或者,您可以将NameIdentifier和IdentityProvider ClaimTypes添加到您的声明中。

代码语言:javascript
复制
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/

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30976980

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档