Asp.net-Mvc

帶有聲明和 AntiforgeryToken 的 MVC 5 OWIN 登錄。我錯過了 ClaimsIdentity 提供商嗎?

  • January 1, 1

我正在嘗試學習 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, "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

@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 因為它可以幫助防止跨站點腳本。

您的聲明身份沒有ClaimTypes.NameIdentifier,您應該在聲明數組中添加更多:

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
};

要將資訊映射到 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/

引用自:https://stackoverflow.com/questions/30976980