public void ValidateTokens_Success_AuthenticatedUserWithUsername() { // Arrange var httpContext = new Mock<HttpContext>().Object; var identity = GetAuthenticatedIdentity("the-user"); var sessionToken = new AntiForgeryToken() { IsSessionToken = true }; var fieldtoken = new AntiForgeryToken() { SecurityToken = sessionToken.SecurityToken, Username = "******", IsSessionToken = false, AdditionalData = "some-additional-data" }; var mockAdditionalDataProvider = new Mock<IAntiForgeryAdditionalDataProvider>(); mockAdditionalDataProvider.Setup(o => o.ValidateAdditionalData(httpContext, "some-additional-data")) .Returns(true); var config = new AntiForgeryOptions(); var tokenProvider = new AntiForgeryTokenProvider( config: config, claimUidExtractor: new Mock<IClaimUidExtractor>().Object, additionalDataProvider: mockAdditionalDataProvider.Object); // Act tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken); // Assert // Nothing to assert - if we got this far, success! }
public void Serialize_FieldToken_WithClaimUid_TokenRoundTripSuccessful() { // Arrange var testSerializer = new AntiForgeryTokenSerializer(_dataProtector.Object); //"01" // Version //+ "705EEDCC7D42F1D6B3B98A593625BB4C" // SecurityToken //+ "00" // IsSessionToken //+ "01" // IsClaimsBased //+ "6F1648E97249AA58754036A67E248CF044F07ECFB0ED387556CE029A4F9A40E0" // ClaimUid //+ "05" // AdditionalData length header //+ "E282AC3437"; // AdditionalData ("€47") as UTF8 var token = new AntiForgeryToken() { SecurityToken = _securityToken, IsSessionToken = false, ClaimUid = _claimUid, AdditionalData = "€47" }; // Act var actualSerializedData = testSerializer.Serialize(token); var deserializedToken = testSerializer.Deserialize(actualSerializedData); // Assert AssertTokensEqual(token, deserializedToken); _dataProtector.Verify(); }
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 string Serialize(AntiForgeryToken token) { string result; using (MemoryStream memoryStream = new MemoryStream()) { using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream)) { binaryWriter.Write(1); binaryWriter.Write(token.SecurityToken.GetData()); binaryWriter.Write(token.IsSessionToken); if (!token.IsSessionToken) { if (token.ClaimUid != null) { binaryWriter.Write(true); binaryWriter.Write(token.ClaimUid.GetData()); } else { binaryWriter.Write(false); binaryWriter.Write(token.Username); } binaryWriter.Write(token.AdditionalData); } binaryWriter.Flush(); result = this._cryptoSystem.Protect(memoryStream.ToArray()); } } return result; }
public void GenerateFormToken_AnonymousUser() { // Arrange var cookieToken = new AntiForgeryToken() { IsSessionToken = true }; var httpContext = new Mock<HttpContext>().Object; var mockIdentity = new Mock<ClaimsIdentity>(); mockIdentity.Setup(o => o.IsAuthenticated) .Returns(false); var config = new AntiForgeryOptions(); var tokenProvider = new AntiForgeryTokenProvider( config: config, claimUidExtractor: null, additionalDataProvider: null); // Act var fieldToken = tokenProvider.GenerateFormToken(httpContext, mockIdentity.Object, cookieToken); // Assert Assert.NotNull(fieldToken); Assert.Equal(cookieToken.SecurityToken, fieldToken.SecurityToken); Assert.False(fieldToken.IsSessionToken); Assert.Empty(fieldToken.Username); Assert.Null(fieldToken.ClaimUid); Assert.Empty(fieldToken.AdditionalData); }
public void GenerateFormToken_AuthenticatedWithoutUsernameAndNoAdditionalData_NoAdditionalData() { // Arrange var cookieToken = new AntiForgeryToken() { IsSessionToken = true }; var httpContext = new Mock<HttpContext>().Object; ClaimsIdentity identity = new MyAuthenticatedIdentityWithoutUsername(); var config = new AntiForgeryOptions(); IClaimUidExtractor claimUidExtractor = new Mock<IClaimUidExtractor>().Object; var tokenProvider = new AntiForgeryTokenProvider( config: config, claimUidExtractor: claimUidExtractor, additionalDataProvider: null); // Act & assert var ex = Assert.Throws<InvalidOperationException>( () => tokenProvider.GenerateFormToken(httpContext, identity, cookieToken)); Assert.Equal( "The provided identity of type " + "'Microsoft.AspNet.Mvc.Core.Test.TokenProviderTest+MyAuthenticatedIdentityWithoutUsername' " + "is marked IsAuthenticated = true but does not have a value for Name. " + "By default, the anti-forgery system requires that all authenticated identities have a unique Name. " + "If it is not possible to provide a unique Name for this identity, " + "consider extending IAdditionalDataProvider by overriding the DefaultAdditionalDataProvider " + "or a custom type that can provide some form of unique identifier for the current user.", ex.Message); }
public void GetCookieToken_CookieIsMissingInRequest_LooksUpCookieInAntiForgeryContext() { // Arrange var requestCookies = new Mock<IReadableStringCollection>(); requestCookies .Setup(o => o.Get(It.IsAny<string>())) .Returns(string.Empty); var mockHttpContext = new Mock<HttpContext>(); mockHttpContext .Setup(o => o.Request.Cookies) .Returns(requestCookies.Object); var contextAccessor = new ScopedInstance<AntiForgeryContext>(); mockHttpContext.SetupGet(o => o.RequestServices) .Returns(GetServiceProvider(contextAccessor)); // add a cookie explicitly. var cookie = new AntiForgeryToken(); contextAccessor.Value = new AntiForgeryContext() { CookieToken = cookie }; var config = new AntiForgeryOptions() { CookieName = _cookieName }; var tokenStore = new AntiForgeryTokenStore( config: config, serializer: null); // Act var token = tokenStore.GetCookieToken(mockHttpContext.Object); // Assert Assert.Equal(cookie, token); }
private static AntiForgeryToken DeserializeImpl(BinaryReader reader) { byte b = reader.ReadByte(); if (b != 1) { return null; } AntiForgeryToken antiForgeryToken = new AntiForgeryToken(); byte[] data = reader.ReadBytes(16); antiForgeryToken.SecurityToken = new BinaryBlob(128, data); antiForgeryToken.IsSessionToken = reader.ReadBoolean(); if (!antiForgeryToken.IsSessionToken) { bool flag = reader.ReadBoolean(); if (flag) { byte[] data2 = reader.ReadBytes(32); antiForgeryToken.ClaimUid = new BinaryBlob(256, data2); } else { antiForgeryToken.Username = reader.ReadString(); } antiForgeryToken.AdditionalData = reader.ReadString(); } if (reader.BaseStream.ReadByte() != -1) { return null; } 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(); } }
private static void AssertTokensEqual(AntiForgeryToken expected, AntiForgeryToken actual) { Assert.NotNull(expected); Assert.NotNull(actual); Assert.Equal(expected.AdditionalData, actual.AdditionalData); Assert.Equal(expected.ClaimUid, actual.ClaimUid); Assert.Equal(expected.IsSessionToken, actual.IsSessionToken); Assert.Equal(expected.SecurityToken, actual.SecurityToken); Assert.Equal(expected.Username, actual.Username); }
public void GetTokens_ExistingValidCookieToken() { // Arrange GenericIdentity identity = new GenericIdentity("some-user"); Mock <HttpContextBase> mockHttpContext = new Mock <HttpContextBase>(); mockHttpContext .Setup(o => o.User) .Returns(new GenericPrincipal(identity, new string[0])); AntiForgeryToken cookieToken = new AntiForgeryToken() { IsSessionToken = true }; AntiForgeryToken formToken = new AntiForgeryToken(); Mock <MockableAntiForgeryTokenSerializer> mockSerializer = new Mock <MockableAntiForgeryTokenSerializer>(MockBehavior.Strict); mockSerializer .Setup(o => o.Deserialize("serialized-old-cookie-token")) .Returns(cookieToken); mockSerializer.Setup(o => o.Serialize(formToken)).Returns("serialized-form-token"); Mock <MockableTokenValidator> mockValidator = new Mock <MockableTokenValidator>( MockBehavior.Strict ); mockValidator .Setup(o => o.GenerateFormToken(mockHttpContext.Object, identity, cookieToken)) .Returns(formToken); mockValidator.Setup(o => o.IsCookieTokenValid(cookieToken)).Returns(true); AntiForgeryWorker worker = new AntiForgeryWorker( config: new MockAntiForgeryConfig(), serializer: mockSerializer.Object, tokenStore: null, validator: mockValidator.Object ); // Act string serializedNewCookieToken, serializedFormToken; worker.GetTokens( mockHttpContext.Object, "serialized-old-cookie-token", out serializedNewCookieToken, out serializedFormToken ); // Assert Assert.Null(serializedNewCookieToken); Assert.Equal("serialized-form-token", serializedFormToken); }
public static bool ValidateAntiForgeryToken(string token, out AntiForgeryToken antiForgeryToken) { byte[] tokenBytes = EncryptionHelper.DecryptAntiForgeryToken(Convert.FromBase64String(token)); using (MemoryStream memoryStream = new MemoryStream(tokenBytes)) { antiForgeryToken = AntiForgeryToken.Deserialize(memoryStream); } return(ValidateAuthToken(antiForgeryToken, Settings.Default.AntiForgeryTokenExpiryInterval)); }
public void IsCookieTokenValid_NullToken_ReturnsFalse() { // Arrange AntiForgeryToken cookieToken = null; TokenValidator validator = new TokenValidator(config: null, claimUidExtractor: null); // Act bool retVal = validator.IsCookieTokenValid(cookieToken); // Assert Assert.False(retVal); }
AntiForgeryToken ITokenValidator.GenerateFormToken( HttpContextBase httpContext, IIdentity identity, AntiForgeryToken cookieToken ) { return((AntiForgeryToken)GenerateFormToken( httpContext, identity, (AntiForgeryToken)cookieToken )); }
public void GetFormInputElement_ExistingInvalidCookieToken() { // Arrange GenericIdentity identity = new GenericIdentity("some-user"); Mock <HttpContextBase> mockHttpContext = new Mock <HttpContextBase>(); mockHttpContext.Setup(o => o.User).Returns(new GenericPrincipal(identity, new string[0])); AntiForgeryToken oldCookieToken = new AntiForgeryToken() { IsSessionToken = true }; AntiForgeryToken newCookieToken = new AntiForgeryToken() { IsSessionToken = true }; AntiForgeryToken formToken = new AntiForgeryToken(); MockAntiForgeryConfig config = new MockAntiForgeryConfig() { FormFieldName = "form-field-name" }; Mock <MockableAntiForgeryTokenSerializer> mockSerializer = new Mock <MockableAntiForgeryTokenSerializer>(MockBehavior.Strict); mockSerializer.Setup(o => o.Serialize(formToken)).Returns("serialized-form-token"); Mock <MockableTokenStore> mockTokenStore = new Mock <MockableTokenStore>(MockBehavior.Strict); mockTokenStore.Setup(o => o.GetCookieToken(mockHttpContext.Object)).Returns(oldCookieToken); mockTokenStore.Setup(o => o.SaveCookieToken(mockHttpContext.Object, newCookieToken)).Verifiable(); Mock <MockableTokenValidator> mockValidator = new Mock <MockableTokenValidator>(MockBehavior.Strict); mockValidator.Setup(o => o.GenerateFormToken(mockHttpContext.Object, identity, newCookieToken)).Returns(formToken); mockValidator.Setup(o => o.IsCookieTokenValid(oldCookieToken)).Returns(false); mockValidator.Setup(o => o.IsCookieTokenValid(newCookieToken)).Returns(true); mockValidator.Setup(o => o.GenerateCookieToken()).Returns(newCookieToken); AntiForgeryWorker worker = new AntiForgeryWorker( config: config, serializer: mockSerializer.Object, tokenStore: mockTokenStore.Object, validator: mockValidator.Object); // Act TagBuilder retVal = worker.GetFormInputElement(mockHttpContext.Object); // Assert Assert.Equal(@"<input name=""form-field-name"" type=""hidden"" value=""serialized-form-token"" />", retVal.ToString(TagRenderMode.SelfClosing)); mockTokenStore.Verify(); }
public void SecurityTokenProperty_PropertySetter_DoesNotUseDefaults() { // Arrange var token = new AntiForgeryToken(); // Act var securityToken = new BinaryBlob(64); token.SecurityToken = securityToken; // Assert Assert.Equal(securityToken, token.SecurityToken); }
public static string OxiteAntiForgeryToken <TModel>(this HtmlHelper <TModel> htmlHelper, Func <TModel, AntiForgeryToken> getToken) where TModel : class { AntiForgeryToken token = getToken(htmlHelper.ViewData.Model); if (token == null) { return(""); } htmlHelper.ViewContext.HttpContext.Response.Cookies.Add(new System.Web.HttpCookie(AntiForgeryToken.TicksName, token.Ticks.ToString())); return(string.Format("<input type=\"hidden\" name=\"{0}\" value=\"{1}\" />", AntiForgeryToken.TokenName, token.Value)); }
public void GenerateCookieToken() { // Arrange TokenValidator tokenValidator = new TokenValidator( config: null, claimUidExtractor: null); // Act AntiForgeryToken retVal = tokenValidator.GenerateCookieToken(); // Assert Assert.NotNull(retVal); }
void ITokenValidator.ValidateTokens( HttpContextBase httpContext, IIdentity identity, AntiForgeryToken cookieToken, AntiForgeryToken formToken ) { ValidateTokens( httpContext, identity, (AntiForgeryToken)cookieToken, (AntiForgeryToken)formToken ); }
public IActionResult Login() { // 3.1.2. Authorization Endpoint const string authorizationEndpoint = "https://localhost:8080/connect/authorize"; // 3.1.2.1. Authentication Request var requestContent = "scope=openid%20profile%20email&" + "response_type=code&" + "client_id=client&" + "redirect_uri=https%3A%2F%2Flocalhost%3A8090%2Fapi%2Fauthorize&" + $"state={WebUtility.UrlEncode(AntiForgeryToken.GetForCurrentUser())}"; return(Redirect($"{authorizationEndpoint}?{requestContent}")); }
public void IsCookieTokenValid_NullToken_ReturnsFalse() { // Arrange AntiForgeryToken cookieToken = null; var tokenProvider = new TokenProvider( config: null, claimUidExtractor: null, additionalDataProvider: null); // Act bool retVal = tokenProvider.IsCookieTokenValid(cookieToken); // Assert Assert.False(retVal); }
public ClientPermissionsController( IClientPermissionsService clientPermissionsService, IdentityServerOptions options, IViewService viewSvc, ILocalizationService localizationService, IEventService eventService, AntiForgeryToken antiForgeryToken) { this.clientPermissionsService = clientPermissionsService; this.options = options; this.viewSvc = viewSvc; this.localizationService = localizationService; this.eventService = eventService; this.antiForgeryToken = antiForgeryToken; }
public void SecurityTokenProperty_GetsAutopopulated() { // Arrange var token = new AntiForgeryToken(); // Act var securityToken = token.SecurityToken; // Assert Assert.NotNull(securityToken); Assert.Equal(AntiForgeryToken.SecurityTokenBitLength, securityToken.BitLength); // check that we're not making a new one each property call Assert.Equal(securityToken, token.SecurityToken); }
public void IsSessionTokenProperty() { // Arrange var token = new AntiForgeryToken(); // Act & assert - 1 Assert.False(token.IsSessionToken); // Act & assert - 2 token.IsSessionToken = true; Assert.True(token.IsSessionToken); // Act & assert - 3 token.IsSessionToken = false; Assert.False(token.IsSessionToken); }
public static bool ValidateAuthToken(AntiForgeryToken antiForgeryToken, TimeSpan validityPeriod) { if (DateTime.UtcNow > antiForgeryToken.ExpiresOn) { return(false); } string callerIPAddress = GetCallerIPAddress(); if (!string.Equals(callerIPAddress, antiForgeryToken.IPAddress)) { return(false); } return(true); }
public void AdditionalDataProperty() { // Arrange var token = new AntiForgeryToken(); // Act & assert - 1 Assert.Equal("", token.AdditionalData); // Act & assert - 2 token.AdditionalData = "additional data"; Assert.Equal("additional data", token.AdditionalData); // Act & assert - 3 token.AdditionalData = null; Assert.Equal("", token.AdditionalData); }
public void UsernameProperty() { // Arrange var token = new AntiForgeryToken(); // Act & assert - 1 Assert.Equal("", token.Username); // Act & assert - 2 token.Username = "******"; Assert.Equal("my username", token.Username); // Act & assert - 3 token.Username = null; Assert.Equal("", token.Username); }
public void SecurityTokenProperty_PropertySetter_DoesNotAllowNulls() { // Arrange var token = new AntiForgeryToken(); // Act token.SecurityToken = null; var securityToken = token.SecurityToken; // Assert Assert.NotNull(securityToken); Assert.Equal(AntiForgeryToken.SecurityTokenBitLength, securityToken.BitLength); // check that we're not making a new one each property call Assert.Equal(securityToken, token.SecurityToken); }
public void IsCookieTokenValid_ValidToken_ReturnsTrue() { // Arrange AntiForgeryToken cookieToken = new AntiForgeryToken() { IsSessionToken = true }; TokenValidator validator = new TokenValidator(config: null, claimUidExtractor: null); // Act bool retVal = validator.IsCookieTokenValid(cookieToken); // Assert Assert.True(retVal); }
public void SaveCookieToken(bool requireSsl, bool?expectedCookieSecureFlag) { // Arrange var token = new AntiForgeryToken(); var mockCookies = new Mock <IResponseCookies>(); // TODO : Once we decide on where to pick this value from enable this. bool defaultCookieSecureValue = expectedCookieSecureFlag ?? false; // pulled from config; set by ctor var cookies = new MockResponseCookieCollection(); cookies.Count = 0; var mockHttpContext = new Mock <HttpContext>(); mockHttpContext.Setup(o => o.Response.Cookies) .Returns(cookies); var contextAccessor = new ContextAccessor <AntiForgeryContext>(); mockHttpContext.SetupGet(o => o.RequestServices) .Returns(GetServiceProvider(contextAccessor)); var mockSerializer = new Mock <IAntiForgeryTokenSerializer>(); mockSerializer.Setup(o => o.Serialize(token)) .Returns("serialized-value"); var config = new AntiForgeryOptions() { CookieName = _cookieName, RequireSSL = requireSsl }; var tokenStore = new AntiForgeryTokenStore( config: config, serializer: mockSerializer.Object); // Act tokenStore.SaveCookieToken(mockHttpContext.Object, token); // Assert Assert.Equal(1, cookies.Count); Assert.NotNull(contextAccessor.Value.CookieToken); Assert.NotNull(cookies); Assert.Equal(_cookieName, cookies.Key); Assert.Equal("serialized-value", cookies.Value); Assert.True(cookies.Options.HttpOnly); Assert.Equal(defaultCookieSecureValue, cookies.Options.Secure); }
public void ClaimUidProperty() { // Arrange var token = new AntiForgeryToken(); // Act & assert - 1 Assert.Null(token.ClaimUid); // Act & assert - 2 BinaryBlob blob = new BinaryBlob(32); token.ClaimUid = blob; Assert.Equal(blob, token.ClaimUid); // Act & assert - 3 token.ClaimUid = null; Assert.Null(token.ClaimUid); }
public AntiForgeryToken GenerateFormToken(HttpContextBase httpContext, IIdentity identity, AntiForgeryToken cookieToken) { Contract.Assert(IsCookieTokenValid(cookieToken)); 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, WebPageResources.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 void ValidateTokens_FieldAndSessionTokensSwapped() { // Arrange var httpContext = new Mock <HttpContext>().Object; ClaimsIdentity identity = new Mock <ClaimsIdentity>().Object; var sessionToken = new AntiForgeryToken() { IsSessionToken = true }; var fieldtoken = new AntiForgeryToken() { IsSessionToken = false }; var config = new AntiForgeryOptions() { CookieName = "my-cookie-name", FormFieldName = "my-form-field-name" }; var tokenProvider = new TokenProvider( config: config, claimUidExtractor: null, additionalDataProvider: null); // Act & assert var ex1 = Assert.Throws <InvalidOperationException>( () => tokenProvider.ValidateTokens(httpContext, identity, fieldtoken, fieldtoken)); Assert.Equal( "Validation of the provided anti-forgery token failed. " + @"The cookie ""my-cookie-name"" and the form field ""my-form-field-name"" were swapped.", ex1.Message); var ex2 = Assert.Throws <InvalidOperationException>( () => tokenProvider.ValidateTokens(httpContext, identity, sessionToken, sessionToken)); Assert.Equal( "Validation of the provided anti-forgery token failed. " + @"The cookie ""my-cookie-name"" and the form field ""my-form-field-name"" were swapped.", ex2.Message); }
public void IsCookieTokenValid_ValidToken_ReturnsTrue() { // Arrange var cookieToken = new AntiForgeryToken() { IsSessionToken = true }; var tokenProvider = new TokenProvider( config: null, claimUidExtractor: null, additionalDataProvider: null); // Act bool retVal = tokenProvider.IsCookieTokenValid(cookieToken); // Assert Assert.True(retVal); }
public void ValidateTokens_UsernameMismatch( string identityUsername, string embeddedUsername ) { // Arrange HttpContextBase httpContext = new Mock <HttpContextBase>().Object; IIdentity identity = new GenericIdentity(identityUsername); AntiForgeryToken sessionToken = new AntiForgeryToken() { IsSessionToken = true }; AntiForgeryToken fieldtoken = new AntiForgeryToken() { SecurityToken = sessionToken.SecurityToken, Username = embeddedUsername, IsSessionToken = false }; Mock <MockableClaimUidExtractor> mockClaimUidExtractor = new Mock <MockableClaimUidExtractor>(); mockClaimUidExtractor.Setup(o => o.ExtractClaimUid(identity)).Returns((object)null); TokenValidator validator = new TokenValidator( config: null, claimUidExtractor: mockClaimUidExtractor.Object ); // Act & assert var ex = Assert.Throws <HttpAntiForgeryException>( () => validator.ValidateTokens(httpContext, identity, sessionToken, fieldtoken) ); Assert.Equal( @"The provided anti-forgery token was meant for user """ + embeddedUsername + @""", but the current user is """ + identityUsername + @""".", ex.Message ); }
public void Validate_FromStore_Failure() { // Arrange GenericIdentity identity = new GenericIdentity("some-user"); Mock <HttpContextBase> mockHttpContext = new Mock <HttpContextBase>(); mockHttpContext .Setup(o => o.User) .Returns(new GenericPrincipal(identity, new string[0])); AntiForgeryToken cookieToken = new AntiForgeryToken(); AntiForgeryToken formToken = new AntiForgeryToken(); Mock <MockableTokenStore> mockTokenStore = new Mock <MockableTokenStore>(); mockTokenStore .Setup(o => o.GetCookieToken(mockHttpContext.Object)) .Returns(cookieToken); mockTokenStore.Setup(o => o.GetFormToken(mockHttpContext.Object)).Returns(formToken); Mock <MockableTokenValidator> mockValidator = new Mock <MockableTokenValidator>(); mockValidator .Setup( o => o.ValidateTokens(mockHttpContext.Object, identity, cookieToken, formToken) ) .Throws(new HttpAntiForgeryException("my-message")); AntiForgeryWorker worker = new AntiForgeryWorker( config: new MockAntiForgeryConfig(), serializer: null, tokenStore: mockTokenStore.Object, validator: mockValidator.Object ); // Act & assert var ex = Assert.Throws <HttpAntiForgeryException>( () => worker.Validate(mockHttpContext.Object) ); Assert.Equal("my-message", ex.Message); }
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 void SaveCookieToken(HttpContextBase httpContext, AntiForgeryToken token) { string serializedToken = _serializer.Serialize(token); var 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); }
/// <summary> /// Initializes a new instance of the <see cref="AuthorizeEndpointController" /> class. /// </summary> /// <param name="viewService">The view service.</param> /// <param name="validator">The validator.</param> /// <param name="responseGenerator">The response generator.</param> /// <param name="interactionGenerator">The interaction generator.</param> /// <param name="options">The options.</param> /// <param name="localizationService">The localization service.</param> /// <param name="events">The event service.</param> /// <param name="antiForgeryToken">The anti forgery token.</param> public AuthorizeEndpointController( IViewService viewService, AuthorizeRequestValidator validator, AuthorizeResponseGenerator responseGenerator, AuthorizeInteractionResponseGenerator interactionGenerator, IdentityServerOptions options, ILocalizationService localizationService, IEventService events, AntiForgeryToken antiForgeryToken) { _viewService = viewService; _options = options; _responseGenerator = responseGenerator; _interactionGenerator = interactionGenerator; _validator = validator; _localizationService = localizationService; _events = events; _antiForgeryToken = antiForgeryToken; }
public void GenerateFormToken_ClaimsBasedIdentity() { // Arrange var cookieToken = new AntiForgeryToken() { IsSessionToken = true }; var httpContext = new Mock <HttpContext>().Object; var identity = GetAuthenticatedIdentity("some-identity"); var config = new AntiForgeryOptions(); byte[] data = new byte[256 / 8]; using (var rng = RandomNumberGenerator.Create()) { rng.GetBytes(data); } var base64ClaimUId = Convert.ToBase64String(data); var expectedClaimUid = new BinaryBlob(256, data); var mockClaimUidExtractor = new Mock <IClaimUidExtractor>(); mockClaimUidExtractor.Setup(o => o.ExtractClaimUid(identity)) .Returns(base64ClaimUId); var tokenProvider = new AntiForgeryTokenProvider( config: config, claimUidExtractor: mockClaimUidExtractor.Object, additionalDataProvider: null); // Act var fieldToken = tokenProvider.GenerateFormToken(httpContext, identity, cookieToken); // Assert Assert.NotNull(fieldToken); Assert.Equal(cookieToken.SecurityToken, fieldToken.SecurityToken); Assert.False(fieldToken.IsSessionToken); Assert.Equal("", fieldToken.Username); Assert.Equal(expectedClaimUid, fieldToken.ClaimUid); Assert.Equal("", fieldToken.AdditionalData); }
public void Validate_FromStore_Success() { // Arrange GenericIdentity identity = new GenericIdentity("some-user"); Mock <HttpContextBase> mockHttpContext = new Mock <HttpContextBase>(); mockHttpContext .Setup(o => o.User) .Returns(new GenericPrincipal(identity, new string[0])); AntiForgeryToken cookieToken = new AntiForgeryToken(); AntiForgeryToken formToken = new AntiForgeryToken(); Mock <MockableTokenStore> mockTokenStore = new Mock <MockableTokenStore>(); mockTokenStore .Setup(o => o.GetCookieToken(mockHttpContext.Object)) .Returns(cookieToken); mockTokenStore.Setup(o => o.GetFormToken(mockHttpContext.Object)).Returns(formToken); Mock <MockableTokenValidator> mockValidator = new Mock <MockableTokenValidator>(); mockValidator .Setup( o => o.ValidateTokens(mockHttpContext.Object, identity, cookieToken, formToken) ) .Verifiable(); AntiForgeryWorker worker = new AntiForgeryWorker( config: new MockAntiForgeryConfig(), serializer: null, tokenStore: mockTokenStore.Object, validator: mockValidator.Object ); // Act worker.Validate(mockHttpContext.Object); // Assert mockValidator.Verify(); }
/* 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 SecurityTokenProperty() { // Arrange AntiForgeryToken token = new AntiForgeryToken(); // Act & assert - 1 BinaryBlob securityToken = token.SecurityToken; Assert.NotNull(securityToken); Assert.Equal(AntiForgeryToken.SecurityTokenBitLength, securityToken.BitLength); Assert.Equal(securityToken, token.SecurityToken); // check that we're not making a new one each property call // Act & assert - 2 securityToken = new BinaryBlob(64); token.SecurityToken = securityToken; Assert.Equal(securityToken, token.SecurityToken); // Act & assert - 3 token.SecurityToken = null; securityToken = token.SecurityToken; Assert.NotNull(securityToken); Assert.Equal(AntiForgeryToken.SecurityTokenBitLength, securityToken.BitLength); Assert.Equal(securityToken, token.SecurityToken); // check that we're not making a new one each property call }
public void ValidateTokens_UsernameMismatch(string identityUsername, string embeddedUsername) { // Arrange var httpContext = new Mock<HttpContext>().Object; var identity = GetAuthenticatedIdentity(identityUsername); var sessionToken = new AntiForgeryToken() { IsSessionToken = true }; var fieldtoken = new AntiForgeryToken() { SecurityToken = sessionToken.SecurityToken, Username = embeddedUsername, IsSessionToken = false }; var mockClaimUidExtractor = new Mock<IClaimUidExtractor>(); mockClaimUidExtractor.Setup(o => o.ExtractClaimUid(identity)) .Returns((string)null); var tokenProvider = new AntiForgeryTokenProvider( config: null, claimUidExtractor: mockClaimUidExtractor.Object, additionalDataProvider: null); // Act & assert var ex = Assert.Throws<InvalidOperationException>( () => tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken)); Assert.Equal( @"The provided anti-forgery token was meant for user """ + embeddedUsername + @""", but the current user is """ + identityUsername + @""".", ex.Message); }
public void ValidateTokens_FieldAndSessionTokensHaveDifferentSecurityKeys() { // Arrange var httpContext = new Mock<HttpContext>().Object; ClaimsIdentity identity = new Mock<ClaimsIdentity>().Object; var sessionToken = new AntiForgeryToken() { IsSessionToken = true }; var fieldtoken = new AntiForgeryToken() { IsSessionToken = false }; var tokenProvider = new AntiForgeryTokenProvider( config: null, claimUidExtractor: null, additionalDataProvider: null); // Act & assert var ex = Assert.Throws<InvalidOperationException>( () => tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken)); Assert.Equal(@"The anti-forgery cookie token and form field token do not match.", ex.Message); }
public void ValidateTokens_FieldAndSessionTokensSwapped() { // Arrange var httpContext = new Mock<HttpContext>().Object; ClaimsIdentity identity = new Mock<ClaimsIdentity>().Object; var sessionToken = new AntiForgeryToken() { IsSessionToken = true }; var fieldtoken = new AntiForgeryToken() { IsSessionToken = false }; var config = new AntiForgeryOptions() { CookieName = "my-cookie-name", FormFieldName = "my-form-field-name" }; var tokenProvider = new AntiForgeryTokenProvider( config: config, claimUidExtractor: null, additionalDataProvider: null); // Act & assert var ex1 = Assert.Throws<InvalidOperationException>( () => tokenProvider.ValidateTokens(httpContext, identity, fieldtoken, fieldtoken)); Assert.Equal( "Validation of the provided anti-forgery token failed. " + @"The cookie ""my-cookie-name"" and the form field ""my-form-field-name"" were swapped.", ex1.Message); var ex2 = Assert.Throws<InvalidOperationException>( () => tokenProvider.ValidateTokens(httpContext, identity, sessionToken, sessionToken)); Assert.Equal( "Validation of the provided anti-forgery token failed. " + @"The cookie ""my-cookie-name"" and the form field ""my-form-field-name"" were swapped.", ex2.Message); }
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()); } } }
public void ValidateTokens_ClaimUidMismatch() { // Arrange var httpContext = new Mock<HttpContext>().Object; var identity = GetAuthenticatedIdentity("the-user"); var sessionToken = new AntiForgeryToken() { IsSessionToken = true }; var fieldtoken = new AntiForgeryToken() { SecurityToken = sessionToken.SecurityToken, IsSessionToken = false, ClaimUid = new BinaryBlob(256) }; var differentToken = new BinaryBlob(256); var mockClaimUidExtractor = new Mock<IClaimUidExtractor>(); mockClaimUidExtractor.Setup(o => o.ExtractClaimUid(identity)) .Returns(Convert.ToBase64String(differentToken.GetData())); var tokenProvider = new AntiForgeryTokenProvider( config: null, claimUidExtractor: mockClaimUidExtractor.Object, additionalDataProvider: null); // Act & assert var ex = Assert.Throws<InvalidOperationException>( () => tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken)); Assert.Equal( @"The provided anti-forgery token was meant for a different claims-based user than the current user.", ex.Message); }
public void GenerateFormToken_ClaimsBasedIdentity() { // Arrange var cookieToken = new AntiForgeryToken() { IsSessionToken = true }; var httpContext = new Mock<HttpContext>().Object; var identity = GetAuthenticatedIdentity("some-identity"); var config = new AntiForgeryOptions(); byte[] data = new byte[256 / 8]; using (var rng = RandomNumberGenerator.Create()) { rng.GetBytes(data); } var base64ClaimUId = Convert.ToBase64String(data); var expectedClaimUid = new BinaryBlob(256, data); var mockClaimUidExtractor = new Mock<IClaimUidExtractor>(); mockClaimUidExtractor.Setup(o => o.ExtractClaimUid(identity)) .Returns(base64ClaimUId); var tokenProvider = new AntiForgeryTokenProvider( config: config, claimUidExtractor: mockClaimUidExtractor.Object, additionalDataProvider: null); // Act var fieldToken = tokenProvider.GenerateFormToken(httpContext, identity, cookieToken); // Assert Assert.NotNull(fieldToken); Assert.Equal(cookieToken.SecurityToken, fieldToken.SecurityToken); Assert.False(fieldToken.IsSessionToken); Assert.Equal("", fieldToken.Username); Assert.Equal(expectedClaimUid, fieldToken.ClaimUid); Assert.Equal("", fieldToken.AdditionalData); }
public void ValidateTokens_AdditionalDataRejected() { // Arrange var httpContext = new Mock<HttpContext>().Object; var identity = new ClaimsIdentity(); var sessionToken = new AntiForgeryToken() { IsSessionToken = true }; var fieldtoken = new AntiForgeryToken() { SecurityToken = sessionToken.SecurityToken, Username = String.Empty, IsSessionToken = false, AdditionalData = "some-additional-data" }; var mockAdditionalDataProvider = new Mock<IAntiForgeryAdditionalDataProvider>(); mockAdditionalDataProvider.Setup(o => o.ValidateAdditionalData(httpContext, "some-additional-data")) .Returns(false); var config = new AntiForgeryOptions(); var tokenProvider = new AntiForgeryTokenProvider( config: config, claimUidExtractor: null, additionalDataProvider: mockAdditionalDataProvider.Object); // Act & assert var ex = Assert.Throws<InvalidOperationException>( () => tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken)); Assert.Equal(@"The provided anti-forgery token failed a custom data check.", ex.Message); }
public void IsCookieTokenValid_ValidToken_ReturnsTrue() { // Arrange var cookieToken = new AntiForgeryToken() { IsSessionToken = true }; var tokenProvider = new AntiForgeryTokenProvider( config: null, claimUidExtractor: null, additionalDataProvider: null); // Act bool retVal = tokenProvider.IsCookieTokenValid(cookieToken); // Assert Assert.True(retVal); }
public void ValidateTokens_Success_ClaimsBasedUser() { // Arrange var httpContext = new Mock<HttpContext>().Object; var identity = GetAuthenticatedIdentity("the-user"); var sessionToken = new AntiForgeryToken() { IsSessionToken = true }; var fieldtoken = new AntiForgeryToken() { SecurityToken = sessionToken.SecurityToken, IsSessionToken = false, ClaimUid = new BinaryBlob(256) }; var mockClaimUidExtractor = new Mock<IClaimUidExtractor>(); mockClaimUidExtractor.Setup(o => o.ExtractClaimUid(identity)) .Returns(Convert.ToBase64String(fieldtoken.ClaimUid.GetData())); var config = new AntiForgeryOptions(); var tokenProvider = new AntiForgeryTokenProvider( config: config, claimUidExtractor: mockClaimUidExtractor.Object, additionalDataProvider: null); // Act tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken); // Assert // Nothing to assert - if we got this far, success! }
public void ValidateTokens_FieldTokenMissing() { // Arrange var httpContext = new Mock<HttpContext>().Object; ClaimsIdentity identity = new Mock<ClaimsIdentity>().Object; var sessionToken = new AntiForgeryToken() { IsSessionToken = true }; AntiForgeryToken fieldtoken = null; var config = new AntiForgeryOptions() { FormFieldName = "my-form-field-name" }; var tokenProvider = new AntiForgeryTokenProvider( config: config, claimUidExtractor: null, additionalDataProvider: null); // Act & assert var ex = Assert.Throws<InvalidOperationException>( () => tokenProvider.ValidateTokens(httpContext, identity, sessionToken, fieldtoken)); Assert.Equal(@"The required anti-forgery form field ""my-form-field-name"" is not present.", ex.Message); }
public void GenerateFormToken_AuthenticatedWithoutUsername_WithAdditionalData() { // Arrange var cookieToken = new AntiForgeryToken() { IsSessionToken = true }; var httpContext = new Mock<HttpContext>().Object; ClaimsIdentity identity = new MyAuthenticatedIdentityWithoutUsername(); var mockAdditionalDataProvider = new Mock<IAntiForgeryAdditionalDataProvider>(); mockAdditionalDataProvider.Setup(o => o.GetAdditionalData(httpContext)) .Returns("additional-data"); var config = new AntiForgeryOptions(); IClaimUidExtractor claimUidExtractor = new Mock<IClaimUidExtractor>().Object; var tokenProvider = new AntiForgeryTokenProvider( config: config, claimUidExtractor: claimUidExtractor, additionalDataProvider: mockAdditionalDataProvider.Object); // Act var fieldToken = tokenProvider.GenerateFormToken(httpContext, identity, cookieToken); // Assert Assert.NotNull(fieldToken); Assert.Equal(cookieToken.SecurityToken, fieldToken.SecurityToken); Assert.False(fieldToken.IsSessionToken); Assert.Empty(fieldToken.Username); Assert.Null(fieldToken.ClaimUid); Assert.Equal("additional-data", fieldToken.AdditionalData); }
public bool IsCookieTokenValid(AntiForgeryToken cookieToken) { return (cookieToken != null && cookieToken.IsSessionToken); }