// [ ENTRY POINT ] // Given an HttpContext, validates that the anti-XSRF tokens contained // in the cookies & form are OK for this request. public void Validate(HttpContextBase httpContext) { CheckSSLConfig(httpContext); // Extract cookie & form tokens AntiForgeryToken cookieToken = _tokenStore.GetCookieToken(httpContext); AntiForgeryToken formToken = _tokenStore.GetFormToken(httpContext); // Validate _validator.ValidateTokens(httpContext, ExtractIdentity(httpContext), cookieToken, formToken); }
public void GetTokens(HttpContextBase httpContext, string serializedOldCookieToken, out string serializedNewCookieToken, out string serializedFormToken) { this.CheckSSLConfig(httpContext); AntiForgeryToken oldCookieToken = this.DeserializeTokenNoThrow(serializedOldCookieToken); AntiForgeryToken token; AntiForgeryToken token2; this.GetTokens(httpContext, oldCookieToken, out token, out token2); serializedNewCookieToken = this.Serialize(token); serializedFormToken = this.Serialize(token2); }
private void GetTokens(HttpContextBase httpContext, AntiForgeryToken oldCookieToken, out AntiForgeryToken newCookieToken, out AntiForgeryToken formToken) { newCookieToken = null; if (!this._validator.IsCookieTokenValid(oldCookieToken)) { AntiForgeryToken antiForgeryToken; newCookieToken = (antiForgeryToken = this._validator.GenerateCookieToken()); oldCookieToken = antiForgeryToken; } formToken = this._validator.GenerateFormToken(httpContext, AntiForgeryWorker.ExtractIdentity(httpContext), oldCookieToken); }
// [ ENTRY POINT ] // Given the serialized string representations of a cookie & form token, // validates that the pair is OK for this request. public void Validate(HttpContextBase httpContext, string cookieToken, string formToken) { CheckSSLConfig(httpContext); // Extract cookie & form tokens AntiForgeryToken deserializedCookieToken = DeserializeToken(cookieToken); AntiForgeryToken deserializedFormToken = DeserializeToken(formToken); // Validate _validator.ValidateTokens(httpContext, ExtractIdentity(httpContext), deserializedCookieToken, deserializedFormToken); }
// [ ENTRY POINT ] // Generates a (cookie, form) serialized token pair for the current user. // The caller may specify an existing cookie value if one exists. If the // 'new cookie value' out param is non-null, the caller *must* persist // the new value to cookie storage since the original value was null or // invalid. This method is side-effect free. public void GetTokens(HttpContextBase httpContext, string serializedOldCookieToken, out string serializedNewCookieToken, out string serializedFormToken) { CheckSSLConfig(httpContext); AntiForgeryToken oldCookieToken = DeserializeTokenNoThrow(serializedOldCookieToken); AntiForgeryToken newCookieToken, formToken; GetTokens(httpContext, oldCookieToken, out newCookieToken, out formToken); serializedNewCookieToken = Serialize(newCookieToken); serializedFormToken = Serialize(formToken); }
private void GetTokens(HttpContextBase httpContext, AntiForgeryToken oldCookieToken, out AntiForgeryToken newCookieToken, out AntiForgeryToken formToken) { newCookieToken = null; if (!_validator.IsCookieTokenValid(oldCookieToken)) { // Need to make sure we're always operating with a good cookie token. oldCookieToken = newCookieToken = _validator.GenerateCookieToken(); } Contract.Assert(_validator.IsCookieTokenValid(oldCookieToken)); formToken = _validator.GenerateFormToken(httpContext, ExtractIdentity(httpContext), oldCookieToken); }
public void SaveCookieToken(HttpContextBase httpContext, AntiForgeryToken token) { string value = this._serializer.Serialize(token); HttpCookie httpCookie = new HttpCookie(this._config.CookieName, value) { HttpOnly = true }; if (this._config.RequireSSL) { httpCookie.Secure = true; } httpContext.Response.Cookies.Set(httpCookie); }
public AntiForgeryToken GenerateFormToken(HttpContextBase httpContext, IIdentity?identity, AntiForgeryToken cookieToken) { Debug.Assert(IsCookieTokenValid(cookieToken)); var formToken = new AntiForgeryToken { SecurityToken = cookieToken.SecurityToken, IsSessionToken = false }; bool requireAuthenticatedUserHeuristicChecks = false; // populate Username and ClaimUid if (identity?.IsAuthenticated == true) { if (!_config.SuppressIdentityHeuristicChecks) { // If the user is authenticated and heuristic checks are not suppressed, // then Username, ClaimUid, or AdditionalData must be set. requireAuthenticatedUserHeuristicChecks = true; } formToken.ClaimUid = _claimUidExtractor.ExtractClaimUid(identity); if (formToken.ClaimUid is null) { formToken.Username = identity.Name; } } // populate AdditionalData if (_config.AdditionalDataProvider != null) { formToken.AdditionalData = _config.AdditionalDataProvider.GetAdditionalData(httpContext); } if (requireAuthenticatedUserHeuristicChecks && String.IsNullOrEmpty(formToken.Username) && formToken.ClaimUid is null && String.IsNullOrEmpty(formToken.AdditionalData)) { // Application says user is authenticated, but we have no identifier for the user. throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, WebPageResources.TokenValidator_AuthenticatedUserWithoutUsername, identity?.GetType())); } return(formToken); }
/* The serialized format of the anti-XSRF token is as follows: * Version: 1 byte integer * SecurityToken: 16 byte binary blob * IsSessionToken: 1 byte Boolean * [if IsSessionToken = true] * +- IsClaimsBased: 1 byte Boolean * | [if IsClaimsBased = true] * | `- ClaimUid: 32 byte binary blob * | [if IsClaimsBased = false] * | `- Username: UTF-8 string with 7-bit integer length prefix * `- AdditionalData: UTF-8 string with 7-bit integer length prefix */ private static AntiForgeryToken DeserializeImpl(BinaryReader reader) { // we can only consume tokens of the same serialized version that we generate byte embeddedVersion = reader.ReadByte(); if (embeddedVersion != TokenVersion) { return(null); } AntiForgeryToken deserializedToken = new AntiForgeryToken(); byte[] securityTokenBytes = reader.ReadBytes( AntiForgeryToken.SecurityTokenBitLength / 8 ); deserializedToken.SecurityToken = new BinaryBlob( AntiForgeryToken.SecurityTokenBitLength, securityTokenBytes ); deserializedToken.IsSessionToken = reader.ReadBoolean(); if (!deserializedToken.IsSessionToken) { bool isClaimsBased = reader.ReadBoolean(); if (isClaimsBased) { byte[] claimUidBytes = reader.ReadBytes(AntiForgeryToken.ClaimUidBitLength / 8); deserializedToken.ClaimUid = new BinaryBlob( AntiForgeryToken.ClaimUidBitLength, claimUidBytes ); } else { deserializedToken.Username = reader.ReadString(); } deserializedToken.AdditionalData = reader.ReadString(); } // if there's still unconsumed data in the stream, fail if (reader.BaseStream.ReadByte() != -1) { return(null); } // success return(deserializedToken); }
public void SaveCookieToken(HttpContextBase httpContext, AntiForgeryToken token) { string serializedToken = _serializer.Serialize(token); HttpCookie newCookie = new HttpCookie(_config.CookieName, serializedToken) { HttpOnly = true }; // Note: don't use "newCookie.Secure = _config.RequireSSL;" since the default // value of newCookie.Secure is automatically populated from the <httpCookies> // config element. if (_config.RequireSSL) { newCookie.Secure = true; } httpContext.Response.Cookies.Set(newCookie); }
public void ValidateTokens(HttpContextBase httpContext, IIdentity identity, AntiForgeryToken sessionToken, AntiForgeryToken fieldToken) { if (sessionToken == null) { throw HttpAntiForgeryException.CreateCookieMissingException(this._config.CookieName); } if (fieldToken == null) { throw HttpAntiForgeryException.CreateFormFieldMissingException(this._config.FormFieldName); } if (!sessionToken.IsSessionToken || fieldToken.IsSessionToken) { throw HttpAntiForgeryException.CreateTokensSwappedException(this._config.CookieName, this._config.FormFieldName); } if (!object.Equals(sessionToken.SecurityToken, fieldToken.SecurityToken)) { throw HttpAntiForgeryException.CreateSecurityTokenMismatchException(); } string text = string.Empty; BinaryBlob binaryBlob = null; if (identity != null && identity.IsAuthenticated) { binaryBlob = this._claimUidExtractor.ExtractClaimUid(identity); if (binaryBlob == null) { text = (identity.Name ?? string.Empty); } } bool flag = text.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || text.StartsWith("https://", StringComparison.OrdinalIgnoreCase); if (!string.Equals(fieldToken.Username, text, flag ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase)) { throw HttpAntiForgeryException.CreateUsernameMismatchException(fieldToken.Username, text); } if (!object.Equals(fieldToken.ClaimUid, binaryBlob)) { throw HttpAntiForgeryException.CreateClaimUidMismatchException(); } if (this._config.AdditionalDataProvider != null && !this._config.AdditionalDataProvider.ValidateAdditionalData(httpContext, fieldToken.AdditionalData)) { throw HttpAntiForgeryException.CreateAdditionalDataCheckFailedException(); } }
public AntiForgeryToken Deserialize(string serializedToken) { try { using (MemoryStream memoryStream = new MemoryStream(this._cryptoSystem.Unprotect(serializedToken))) { using (BinaryReader binaryReader = new BinaryReader(memoryStream)) { AntiForgeryToken antiForgeryToken = AntiForgeryTokenSerializer.DeserializeImpl(binaryReader); if (antiForgeryToken != null) { return(antiForgeryToken); } } } } catch { } throw HttpAntiForgeryException.CreateDeserializationFailedException(); }
// [ ENTRY POINT ] // Generates an anti-XSRF token pair for the current user. The return // value is the hidden input form element that should be rendered in // the <form>. This method has a side effect: it may set a response // cookie. public TagBuilder GetFormInputElement(HttpContextBase httpContext) { CheckSSLConfig(httpContext); AntiForgeryToken oldCookieToken = GetCookieTokenNoThrow(httpContext); AntiForgeryToken newCookieToken, formToken; GetTokens(httpContext, oldCookieToken, out newCookieToken, out formToken); if (newCookieToken != null) { // If a new cookie was generated, persist it. _tokenStore.SaveCookieToken(httpContext, newCookieToken); } // <input type="hidden" name="__AntiForgeryToken" value="..." /> TagBuilder retVal = new TagBuilder("input"); retVal.Attributes["type"] = "hidden"; retVal.Attributes["name"] = _config.FormFieldName; retVal.Attributes["value"] = _serializer.Serialize(formToken); return(retVal); }
public TagBuilder GetFormInputElement(HttpContextBase httpContext) { this.CheckSSLConfig(httpContext); AntiForgeryToken cookieTokenNoThrow = this.GetCookieTokenNoThrow(httpContext); AntiForgeryToken antiForgeryToken; AntiForgeryToken token; this.GetTokens(httpContext, cookieTokenNoThrow, out antiForgeryToken, out token); if (antiForgeryToken != null) { this._tokenStore.SaveCookieToken(httpContext, antiForgeryToken); } if (!this._config.SuppressXFrameOptionsHeader) { httpContext.Response.AddHeader("X-Frame-Options", "SAMEORIGIN"); } TagBuilder tagBuilder = new TagBuilder("input"); tagBuilder.Attributes["type"] = "hidden"; tagBuilder.Attributes["name"] = this._config.FormFieldName; tagBuilder.Attributes["value"] = this._serializer.Serialize(token); return(tagBuilder); }
public string Serialize(AntiForgeryToken token) { Contract.Assert(token != null); using (MemoryStream stream = new MemoryStream()) { using (BinaryWriter writer = new BinaryWriter(stream)) { writer.Write(TokenVersion); writer.Write(token.SecurityToken.GetData()); writer.Write(token.IsSessionToken); if (!token.IsSessionToken) { if (token.ClaimUid != null) { writer.Write( true /* isClaimsBased */ ); writer.Write(token.ClaimUid.GetData()); } else { writer.Write( false /* isClaimsBased */ ); writer.Write(token.Username); } writer.Write(token.AdditionalData); } writer.Flush(); return(_cryptoSystem.Protect(stream.ToArray())); } } }
// [ ENTRY POINT ] // Generates an anti-XSRF token pair for the current user. The return // value is the hidden input form element that should be rendered in // the <form>. This method has a side effect: it may set a response // cookie. public TagBuilder GetFormInputElement(HttpContextBase httpContext) { CheckSSLConfig(httpContext); AntiForgeryToken oldCookieToken = GetCookieTokenNoThrow(httpContext); AntiForgeryToken newCookieToken, formToken; GetTokens(httpContext, oldCookieToken, out newCookieToken, out formToken); if (newCookieToken != null) { // If a new cookie was generated, persist it. _tokenStore.SaveCookieToken(httpContext, newCookieToken); } if (!_config.SuppressXFrameOptionsHeader) { // Adding X-Frame-Options header to prevent ClickJacking. See // http://tools.ietf.org/html/draft-ietf-websec-x-frame-options-10 // for more information. const string FrameHeaderName = "X-Frame-Options"; if (httpContext.Response.Headers[FrameHeaderName] == null) { httpContext.Response.AddHeader(FrameHeaderName, "SAMEORIGIN"); } } // <input type="hidden" name="__AntiForgeryToken" value="..." /> TagBuilder retVal = new TagBuilder("input"); retVal.Attributes["type"] = "hidden"; retVal.Attributes["name"] = _config.FormFieldName; retVal.Attributes["value"] = _serializer.Serialize(formToken); return(retVal); }
public AntiForgeryToken Deserialize(string serializedToken) { try { using (MemoryStream stream = new MemoryStream(_cryptoSystem.Unprotect(serializedToken))) { using (BinaryReader reader = new BinaryReader(stream)) { AntiForgeryToken token = DeserializeImpl(reader); if (token != null) { return(token); } } } } catch { // swallow all exceptions - homogenize error if something went wrong } // if we reached this point, something went wrong deserializing throw HttpAntiForgeryException.CreateDeserializationFailedException(); }
public AntiForgeryToken GenerateFormToken(HttpContextBase httpContext, IIdentity identity, AntiForgeryToken cookieToken) { AntiForgeryToken antiForgeryToken = new AntiForgeryToken { SecurityToken = cookieToken.SecurityToken, IsSessionToken = false }; bool flag = false; if (identity != null && identity.IsAuthenticated) { if (!this._config.SuppressIdentityHeuristicChecks) { flag = true; } antiForgeryToken.ClaimUid = this._claimUidExtractor.ExtractClaimUid(identity); if (antiForgeryToken.ClaimUid == null) { antiForgeryToken.Username = identity.Name; } } if (this._config.AdditionalDataProvider != null) { antiForgeryToken.AdditionalData = this._config.AdditionalDataProvider.GetAdditionalData(httpContext); } if (flag && string.IsNullOrEmpty(antiForgeryToken.Username) && antiForgeryToken.ClaimUid == null && string.IsNullOrEmpty(antiForgeryToken.AdditionalData)) { throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, WebPageResources.TokenValidator_AuthenticatedUserWithoutUsername, new object[] { identity.GetType() })); } return(antiForgeryToken); }
public void ValidateTokens( HttpContextBase httpContext, IIdentity identity, AntiForgeryToken sessionToken, AntiForgeryToken fieldToken ) { // Were the tokens even present at all? if (sessionToken == null) { throw HttpAntiForgeryException.CreateCookieMissingException(_config.CookieName); } if (fieldToken == null) { throw HttpAntiForgeryException.CreateFormFieldMissingException( _config.FormFieldName ); } // Do the tokens have the correct format? if (!sessionToken.IsSessionToken || fieldToken.IsSessionToken) { throw HttpAntiForgeryException.CreateTokensSwappedException( _config.CookieName, _config.FormFieldName ); } // Are the security tokens embedded in each incoming token identical? if (!Equals(sessionToken.SecurityToken, fieldToken.SecurityToken)) { throw HttpAntiForgeryException.CreateSecurityTokenMismatchException(); } // Is the incoming token meant for the current user? string currentUsername = String.Empty; BinaryBlob currentClaimUid = null; if (identity != null && identity.IsAuthenticated) { currentClaimUid = _claimUidExtractor.ExtractClaimUid(identity); if (currentClaimUid == null) { currentUsername = identity.Name ?? String.Empty; } } // OpenID and other similar authentication schemes use URIs for the username. // These should be treated as case-sensitive. bool useCaseSensitiveUsernameComparison = currentUsername.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || currentUsername.StartsWith("https://", StringComparison.OrdinalIgnoreCase); if ( !String.Equals( fieldToken.Username, currentUsername, (useCaseSensitiveUsernameComparison) ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase ) ) { throw HttpAntiForgeryException.CreateUsernameMismatchException( fieldToken.Username, currentUsername ); } if (!Equals(fieldToken.ClaimUid, currentClaimUid)) { throw HttpAntiForgeryException.CreateClaimUidMismatchException(); } // Is the AdditionalData valid? if ( _config.AdditionalDataProvider != null && !_config.AdditionalDataProvider.ValidateAdditionalData( httpContext, fieldToken.AdditionalData ) ) { throw HttpAntiForgeryException.CreateAdditionalDataCheckFailedException(); } }
public bool IsCookieTokenValid(AntiForgeryToken cookieToken) { return(cookieToken != null && cookieToken.IsSessionToken); }
private string Serialize(AntiForgeryToken token) { return((token != null) ? _serializer.Serialize(token) : null); }