// [ 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 ] // 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); }
// [ 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(); } #if NET_4_0 Contract.Assert(_validator.IsCookieTokenValid(oldCookieToken)); #endif formToken = _validator.GenerateFormToken(httpContext, ExtractIdentity(httpContext), oldCookieToken); }
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 AntiForgeryToken GenerateFormToken(HttpContextBase httpContext, IIdentity identity, AntiForgeryToken cookieToken) { #if NET_4_0 Contract.Assert(IsCookieTokenValid(cookieToken)); #endif AntiForgeryToken formToken = new AntiForgeryToken() { SecurityToken = cookieToken.SecurityToken, IsSessionToken = false }; bool requireAuthenticatedUserHeuristicChecks = false; // populate Username and ClaimUid if (identity != null && identity.IsAuthenticated) { 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 == 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 == 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, MvcResources.TokenValidator_AuthenticatedUserWithoutUsername, identity.GetType())); } return(formToken); }
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 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) { #if NET_4_0 Contract.Assert(IsCookieTokenValid(cookieToken)); #endif AntiForgeryToken formToken = new AntiForgeryToken() { SecurityToken = cookieToken.SecurityToken, IsSessionToken = false }; bool requireAuthenticatedUserHeuristicChecks = false; // populate Username and ClaimUid if (identity != null && identity.IsAuthenticated) { 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 == 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 == 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, MvcResources.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); }
// [ 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 bool IsCookieTokenValid(AntiForgeryToken cookieToken) { return (cookieToken != null && cookieToken.IsSessionToken); }
private string Serialize(AntiForgeryToken token) { return((token != null) ? _serializer.Serialize(token) : null); }
private string Serialize(AntiForgeryToken token) { return (token != null) ? _serializer.Serialize(token) : null; }
public bool IsCookieTokenValid(AntiForgeryToken cookieToken) { return(cookieToken != null && cookieToken.IsSessionToken); }