See Microsoft source code verification Token [CSRF] MVC5

In MVC5 know, prior to action method of adding [ValidateAntiForgeryToken] , will verify from the user's own form, verify cook the token and from the form of the token , it is the same
for the convenience of better debugging, direct call its verification method AntiForgery.Validate ();

 // [AcceptVerbs(HttpVerbs.Post)] netCore没有这个
 [HttpPost]
// [ValidateAntiForgeryToken]
 public JsonResult Index(int a=1/*IFormCollection collection*/)
 {
     HttpCookie antiForgeryCookie = Request.Cookies[AntiForgeryConfig.CookieName];
     string cookieValue = antiForgeryCookie != null ? antiForgeryCookie.Value : null;
     
     AntiForgery.Validate(cookieValue, Request["__RequestVerificationToken"]);//Validate,就是框架源码验证的核心
     ModelState.AddModelError("", "1111111111111");
     return Json("验证成功!");
 }

Open the Validate method

///  <Summary> verify whether the input data from the HTML form fields of user data has been submitted. </ Summary> 
///  <param name = "cookieToken"> cookies token value. </ param> 
///  <param name = "formToken"> token formats. </ param> 
[EditorBrowsable (EditorBrowsableState.Advanced)]
 public  static  void the Validate ( String cookieToken, String formToken) 
{ 
  IF (the HttpContext.Current == null )
     the throw  new new ArgumentException The (WebPageResources.HttpContextUnavailable); 
  AntiForgery._worker.Validate ((HttpContextBase ) new new HttpContextWrapper(HttpContext.Current), cookieToken, formToken);
}

Open AntiForgery._worker.Validate method

public void Validate(HttpContextBase httpContext, string cookieToken, string formToken)
{
  this.CheckSSLConfig(httpContext);
  AntiForgeryToken cookieToken1 = this.DeserializeToken(cookieToken);//来自Cookie的token
  AntiForgeryToken formToken1 = this.DeserializeToken(formToken);//来自form表单的token
  this._validator.ValidateTokens(httpContext, AntiForgeryWorker.ExtractIdentity(httpContext), cookieToken1, formToken1);
}

Continue to open  this._validator.ValidateTokens () , method

internal interface ITokenValidator
{
  AntiForgeryToken GenerateCookieToken();

  AntiForgeryToken GenerateFormToken(HttpContextBase httpContext,IIdentity identity,AntiForgeryToken cookieToken);

  bool IsCookieTokenValid(AntiForgeryToken cookieToken);

  void ValidateTokens(HttpContextBase httpContext,IIdentity identity,AntiForgeryToken cookieToken,AntiForgeryToken formToken);
}

Because ValidateTokens is the need to achieve, to find realization, ValidateTokens TokenValidator class, it is the concrete realization

public void ValidateTokens( HttpContextBase httpContext,  IIdentity identity,  AntiForgeryToken sessionToken,  AntiForgeryToken fieldToken)
{
  if (sessionToken == null)//1.来自cookies的token=null,直接验证失败
    throw HttpAntiForgeryException.CreateCookieMissingException(this._config.CookieName);
  if (fieldToken == null)  //2.来自表单的token=null,直接验证失败
    throw HttpAntiForgeryException.CreateFormFieldMissingException(this._config.FormFieldName);
  if (!sessionToken.IsSessionToken || fieldToken.IsSessionToken) // 3.验证cookietoken的IsSessionToken 是否
    throw HttpAntiForgeryException.CreateTokensSwappedException(this._config.CookieName, this._config.FormFieldName);
  if (!object.Equals((object) sessionToken.SecurityToken, (object) fieldToken.SecurityToken))
    throw HttpAntiForgeryException.CreateSecurityTokenMismatchException();
  string str = string.Empty;
  BinaryBlob binaryBlob = (BinaryBlob) null;
  if (identity != null && identity.IsAuthenticated)
  {
    binaryBlob = this._claimUidExtractor.ExtractClaimUid(identity);
    if (binaryBlob == null)
      str = identity.Name ?? string.Empty;
  }
  bool flag = str.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || str.StartsWith("https://", StringComparison.OrdinalIgnoreCase);
  if (!string.Equals(fieldToken.Username, str, flag ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase))
    throw HttpAntiForgeryException.CreateUsernameMismatchException(fieldToken.Username, str);
  if (!object.Equals((object) fieldToken.ClaimUid, (object) binaryBlob))
    throw HttpAntiForgeryException.CreateClaimUidMismatchException();
  if (this._config.AdditionalDataProvider != null && !this._config.AdditionalDataProvider.ValidateAdditionalData(httpContext, fieldToken.AdditionalData))
    throw HttpAntiForgeryException.CreateAdditionalDataCheckFailedException();
}

Through this method, it can be seen that the formula is fully validated method that is most critical logical token verification codes
core verified, that the two token (AntiForgeryToken two objects), is a cooktoken, a formtoken, verify same respective properties, IsSessionToken expressed Cookie token is true, otherwise the token form
1. after the opening of the security tagging, FormToken or CookieToken wherein a blank value! That is as long as the missing form token or tokens Cookie, verification must be a failure.
2. The value of the security token security token is not equal!
3. The authorization information related to the security token is inconsistent! Such as inconsistencies authentication and authorization user name!
4. The security token own markup errors, IsSessionToken expressed Cookie token is true, otherwise the form token, if this property is set incorrectly, validation fails!
5. Other also determines whether the value of this attribute AdditionalDataProvider

Links: https: //shiyousan.com/post/636402934261643641
can be found, to authentication to authenticate, wherein the core or the sealing AntiForgeryToken class,

 

internal sealed class AntiForgeryToken
{
  internal const int SecurityTokenBitLength = 128;
  internal const int ClaimUidBitLength = 256;
  private string _additionalData;
  private BinaryBlob _securityToken;
  private string _username;

  public string AdditionalData
  {
    get
    {
      return this._additionalData ?? string.Empty;
    }
    set
    {
      this= ._additionalData value; 
    } 
  } 

  public BinaryBlob ClaimUid { GET ; SET ;} 

  // to true token represents Cookie, otherwise form a token 
  public  BOOL IsSessionToken { GET ; SET ;} 

  // security token 
  public BinaryBlob SecurityToken 
  { 
    GET 
    { 
      IF ( the this ._securityToken == null )
         the this ._securityToken = new new BinaryBlob ( 128 );
       return  the this ._securityToken; 
    }
    set
    {
      this._securityToken = value;
    }
  }

  public string Username
  {
    get
    {
      return this._username ?? string.Empty;
    }
    set
    {
      this._username = value;
    }
  }
}

 

 

 

 

 

 

Guess you like

Origin www.cnblogs.com/Qintai/p/11828086.html
Recommended