private void VerifyPreferHeaderOnRequest(HttpRequestData request, DataServiceResponsePreference responsePreference) { bool preferExists = request.Headers.Keys.Contains(HttpHeaders.Prefer); // NOTE: if the prefer header is not present, we cannot tell if it should have been, because we don't // know here whether or not this is an entity-specific operation // In other words: even though this is POST/PUT/PATCH, it might be AddLink, SetLink, or a media-resource // update, and therefore should NOT have a prefer header // For now, this component will simply verify what it can, and the rest will be covered by the // verification of the requests sent during SaveChanges. We may be able to remove this component altogether. if (responsePreference == DataServiceResponsePreference.None || !this.IsCreateOrUpdate(request.GetEffectiveVerb())) { this.Assert.IsFalse(preferExists, "Unexpected presence of Prefer Header"); } else if (preferExists) { string value = request.Headers[HttpHeaders.Prefer]; if (responsePreference == DataServiceResponsePreference.IncludeContent) { this.Assert.AreEqual(HttpHeaders.ReturnContent, value, "Incorrect value of Prefer Header"); } if (responsePreference == DataServiceResponsePreference.NoContent) { this.Assert.AreEqual(HttpHeaders.ReturnNoContent, value, "Incorrect value of Prefer Header"); } } }
public void SignInCommand_Run_With_InvalidIdp_ThrowsException() { var request = new HttpRequestData("GET", new Uri("http://localhost/signin?idp=no-such-idp-in-config")); Action a = () => new SignInCommand().Run(request); a.ShouldThrow<InvalidOperationException>().WithMessage("Unknown idp"); }
public void Saml2Binding_Get_ReturnsSaml2Postbinding() { var r = new HttpRequestData("POST", new Uri("http://example.com"), new KeyValuePair<string, string[]>[] { new KeyValuePair<string, string[]>("SAMLResponse", new string[] { "Some Data" }) }); Saml2Binding.Get(r).Should().BeOfType<Saml2PostBinding>(); }
/// <summary> /// Verifies the headers present on the HTTP request /// </summary> /// <param name="context">The data service context</param> /// <param name="request">The http request</param> /// <param name="response">The http response</param> public void HandleRequestResponsePair(DataServiceContext context, HttpRequestData request, HttpResponseData response) { #if !SILVERLIGHT || WIN8 this.VerifyPreferHeaderOnRequest(request, context.AddAndUpdateResponsePreference); if (context.AddAndUpdateResponsePreference != DataServiceResponsePreference.None && this.IsCreateOrUpdate(request.GetEffectiveVerb())) { this.VerifyVersionHeaders(request); } #endif }
private void HandleRequestResponsePair(DataServiceContext context, HttpRequestData request, HttpResponseData response) { ExceptionUtilities.CheckArgumentNotNull(context, "context"); ExceptionUtilities.CheckArgumentNotNull(request, "request"); ExceptionUtilities.CheckArgumentNotNull(response, "response"); this.Assert.AreSame(this.Input.Context, context, "Handle request/response pair called with unexpected context"); this.httpLog.Add(new KeyValuePair<HttpRequestData, HttpResponseData>(request, response)); }
public void SignInCommand_Run_With_Idp2_ReturnsAuthnRequestForSecondIdp() { var secondIdp = IdentityProvider.ActiveIdentityProviders.Skip(1).First(); var secondDestination = secondIdp.AssertionConsumerServiceUrl; var secondEntityId = secondIdp.EntityId; var request = new HttpRequestData("GET", new Uri("http://sp.example.com?idp=" + HttpUtility.UrlEncode(secondEntityId.Id))); var subject = new SignInCommand().Run(request); subject.Location.Host.Should().Be(secondDestination.Host); }
public void AcsCommand_Run_ErrorOnNotBase64InFormResponse() { var r = new HttpRequestData("POST", new Uri("http://localhost"), new KeyValuePair<string, string[]>[] { new KeyValuePair<string, string[]>("SAMLResponse", new string[] { "#¤!2" }) }); Action a = () => new AcsCommand().Run(r); a.ShouldThrow<BadFormatSamlResponseException>() .WithMessage("The SAML Response did not contain valid BASE64 encoded data.") .WithInnerException<FormatException>(); }
/// <summary> /// Builds a new instance of the ODataPayloadContext class based on an ODataRequest. /// </summary> /// <param name="request">The request to build the payload context from.</param> /// <returns>The payload context for the request.</returns> public static ODataPayloadContext BuildPayloadContextFromRequest(HttpRequestData<ODataUri, ODataPayloadBody> request) { var payloadContext = new ODataPayloadContext(); ODataUri uri = request.Uri; if (uri != null) { payloadContext = BuildODataPayloadContextFromODataUri(uri); } payloadContext.EffectiveRequestVerb = request.GetEffectiveVerb(); return payloadContext; }
public void AcsCommand_Run_ErrorOnIncorrectXml() { var encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes("<foo />")); var r = new HttpRequestData("POST", new Uri("http://localhost"), new KeyValuePair<string, string[]>[] { new KeyValuePair<string, string[]>("SAMLResponse", new string[] { encoded }) }); Action a = () => new AcsCommand().Run(r); a.ShouldThrow<BadFormatSamlResponseException>() .WithMessage("The SAML response contains incorrect XML") .WithInnerException<XmlException>(); }
public void HttpRequestData_Ctor() { var url = new Uri("http://example.com/someurl?name=DROP%20TABLE%20STUDENTS"); var request = Substitute.For<HttpRequestBase>(); request.HttpMethod.Returns("GET"); request.Url.Returns(url); request.Form.Returns(new NameValueCollection { { "Key", "Value" } }); var subject = new HttpRequestData(request); var expected = new HttpRequestData( "GET", url, new KeyValuePair<string, string[]>[] { new KeyValuePair<string, string[]>("Key", new string[] { "Value" }) }); subject.ShouldBeEquivalentTo(expected); }
/// <summary> /// Generates the entity model for a DataService refered to via the ServiceMetadataDocumentUri parameter /// </summary> /// <returns>An entity model representing the Data Service</returns> public EntityModelSchema GenerateModel() { ExceptionUtilities.CheckStringArgumentIsNotNullOrEmpty(this.ServiceMetadataDocumentUri, "Using this ModelGenrator requires setting the ServiceMetadataDocumentUri test parameter"); HttpRequestData metadataDocumentRequest = new HttpRequestData() { Uri = new Uri(this.ServiceMetadataDocumentUri) }; HttpResponseData response = this.HttpStack.GetResponse(metadataDocumentRequest); var encoding = response.GetEncodingFromHeadersOrDefault(); string metadataDocumentString = encoding.GetString(response.Body); XDocument metadataDocument = XDocument.Parse(metadataDocumentString); XElement edmxElement = metadataDocument.Root; var metadataPayloadElement = this.PayloadElementConverter.ConvertToPayloadElement(edmxElement) as MetadataPayloadElement; ExceptionUtilities.CheckObjectNotNull(metadataPayloadElement, "MetadataPayloadElement should not be null"); var model = metadataPayloadElement.EntityModelSchema; new SetDefaultCollectionTypesFixup().Fixup(model); return model; }
public void SignInCommand_Run_MapsReturnUrl() { var defaultDestination = IdentityProvider.ActiveIdentityProviders.First() .AssertionConsumerServiceUrl; var httpRequest = new HttpRequestData("GET", new Uri("http://localhost/signin?ReturnUrl=/Return.aspx")); var subject = new SignInCommand().Run(httpRequest); var idp = IdentityProvider.ActiveIdentityProviders.First(); var authnRequest = idp.CreateAuthenticateRequest(null); var requestId = AuthnRequestHelper.GetRequestId(subject.Location); StoredRequestState storedAuthnData; PendingAuthnRequests.TryRemove(new System.IdentityModel.Tokens.Saml2Id(requestId), out storedAuthnData); storedAuthnData.ReturnUri.Should().Be("http://localhost/Return.aspx"); }
/// <summary> /// Deserializes the given request's binary payload into a batch payload /// </summary> /// <param name="request">The request to deserialize</param> /// <returns>The deserialized batch request payload</returns> public BatchRequestPayload DeserializeBatchRequest(HttpRequestData request) { var encoding = request.GetEncodingFromHeadersOrDefault(); MultipartMimeData<MimePartData<byte[]>> split; ExceptionUtilities.Assert(TrySplitMimePart(request, encoding, out split), "Failed to split batch response body"); var batchRequest = new BatchRequestPayload(); foreach (var subPart in split.ToList()) { MultipartMimeData<MimePartData<byte[]>> splitChangeset; if (TrySplitMimePart(subPart, encoding, out splitChangeset)) { var changeset = new BatchRequestChangeset(); changeset.Headers.AddRange(splitChangeset.Headers); foreach (var changesetPart in splitChangeset) { if (changesetPart.Body != null) { if (changesetPart.Body.Length > 0) { changeset.Add(this.BuildRequestFromPart(changesetPart, encoding)); } } } batchRequest.Add(changeset); } else { batchRequest.Add(this.BuildRequestFromPart(subPart, encoding)); } } return batchRequest; }
private void RelayStateAsReturnUrl(string relayState, IOptions options, [CallerMemberName] string caller = null) { if (string.IsNullOrEmpty(caller)) { throw new ArgumentNullException(nameof(caller)); } var response = @"<saml2p:Response xmlns:saml2p=""urn:oasis:names:tc:SAML:2.0:protocol"" xmlns:saml2=""urn:oasis:names:tc:SAML:2.0:assertion"" ID = """ + caller + @""" Version=""2.0"" IssueInstant=""2013-01-01T00:00:00Z""> <saml2:Issuer> https://idp5.example.com </saml2:Issuer> <saml2p:Status> <saml2p:StatusCode Value=""urn:oasis:names:tc:SAML:2.0:status:Success"" /> </saml2p:Status> <saml2:Assertion Version=""2.0"" ID=""" + caller + @"_Assertion"" IssueInstant=""2013-09-25T00:00:00Z""> <saml2:Issuer>https://idp5.example.com</saml2:Issuer> <saml2:Subject> <saml2:NameID>SomeUser</saml2:NameID> <saml2:SubjectConfirmation Method=""urn:oasis:names:tc:SAML:2.0:cm:bearer"" /> </saml2:Subject> <saml2:Conditions NotOnOrAfter=""2100-01-01T00:00:00Z"" /> </saml2:Assertion> </saml2p:Response>"; var responseFormValue = Convert.ToBase64String (Encoding.UTF8.GetBytes(SignedXmlHelper.SignXml(response))); var formData = new List <KeyValuePair <string, IEnumerable <string> > > { new KeyValuePair <string, IEnumerable <string> >("SAMLResponse", new string[] { responseFormValue }), }; if (relayState != null) { formData.Add(new KeyValuePair <string, IEnumerable <string> >("RelayState", new string[] { relayState })); } var r = new HttpRequestData( "POST", new Uri("http://localhost"), "/ModulePath", formData, null); var ids = new ClaimsIdentity[] { new ClaimsIdentity("Federation") }; ids[0].AddClaim(new Claim(ClaimTypes.NameIdentifier, "SomeUser", null, "https://idp5.example.com")); var expected = new CommandResult() { Principal = new ClaimsPrincipal(ids), HttpStatusCode = HttpStatusCode.SeeOther, Location = relayState != null ? new Uri(relayState, UriKind.RelativeOrAbsolute) : null, }; new AcsCommand().Run(r, options) .Location.OriginalString.Should().Be(relayState); }
public void LogoutCommand_Run_HandlesLogoutRequest_ReceivedThroughRedirectBinding() { var request = new Saml2LogoutRequest() { DestinationUrl = new Uri("http://sp.example.com/path/Saml2/logout"), Issuer = new EntityId("https://idp.example.com"), SigningCertificate = SignedXmlHelper.TestCert, NameId = new Saml2NameIdentifier("NameId"), SessionIndex = "SessionID", SigningAlgorithm = SecurityAlgorithms.RsaSha256Signature }; var bindResult = Saml2Binding.Get(Saml2BindingType.HttpRedirect) .Bind(request); var httpRequest = new HttpRequestData("GET", bindResult.Location); var options = StubFactory.CreateOptions(); options.SPOptions.ServiceCertificates.Add(SignedXmlHelper.TestCert); CommandResult notifiedCommandResult = null; options.Notifications.LogoutCommandResultCreated = cr => { notifiedCommandResult = cr; }; // We're using unbind to verify the created message and UnBind // expects the issuer to be a known Idp for signature validation. // Add a dummy with the right issuer name and key. var dummyIdp = new IdentityProvider(options.SPOptions.EntityId, options.SPOptions); dummyIdp.SigningKeys.AddConfiguredKey(SignedXmlHelper.TestCert); options.IdentityProviders.Add(dummyIdp); var actual = CommandFactory.GetCommand(CommandFactory.LogoutCommandName) .Run(httpRequest, options); var expected = new CommandResult() { HttpStatusCode = HttpStatusCode.SeeOther, TerminateLocalSession = true // Deliberately not comparing Location }; HttpUtility.ParseQueryString(actual.Location.Query)["Signature"] .Should().NotBeNull("LogoutResponse should be signed"); actual.Should().BeEquivalentTo(expected, opt => opt.Excluding(cr => cr.Location)); actual.Should().BeSameAs(notifiedCommandResult); var actualUnbindResult = Saml2Binding.Get(Saml2BindingType.HttpRedirect) .Unbind(new HttpRequestData("GET", actual.Location), options); var actualMessage = actualUnbindResult.Data; var expectedMessage = XmlHelpers.XmlDocumentFromString( $@"<samlp:LogoutResponse xmlns:samlp=""urn:oasis:names:tc:SAML:2.0:protocol"" xmlns=""urn:oasis:names:tc:SAML:2.0:assertion"" Destination=""https://idp.example.com/logout"" Version=""2.0""> <Issuer>{options.SPOptions.EntityId.Id}</Issuer> <samlp:Status> <samlp:StatusCode Value=""urn:oasis:names:tc:SAML:2.0:status:Success""/> </samlp:Status> </samlp:LogoutResponse>").DocumentElement; // Set generated attributes to actual values. expectedMessage.SetAttribute("ID", actualMessage.GetAttribute("ID")); expectedMessage.SetAttribute("IssueInstant", actualMessage.GetAttribute("IssueInstant")); expectedMessage.SetAttribute("InResponseTo", request.Id.Value); actualMessage.Should().BeEquivalentTo(expectedMessage); actualUnbindResult.RelayState.Should().Be(request.RelayState); actualUnbindResult.TrustLevel.Should().Be(TrustLevel.Signature); }
public override UnbindResult Unbind(HttpRequestData request, IOptions options) { throw new NotImplementedException( $"{nameof(StubSaml2Binding)}.{nameof(Unbind)} was called"); }
public static HttpResponseData CreateBadRequestErrorMessageResponse(this HttpRequestData httpRequestData, string message) { return(httpRequestData.CreateStringMessageResponse(HttpStatusCode.BadRequest, message)); }
public async Task Saml2Handler_Acs_Works() { var context = new Saml2HandlerTestContext(); context.HttpContext.Request.Method = "POST"; context.HttpContext.Request.Path = "/Saml2/Acs"; var authProps = new AuthenticationProperties() { IssuedUtc = new DateTimeOffset(DateTime.UtcNow) }; authProps.Items["Test"] = "TestValue"; var state = new StoredRequestState( new EntityId("https://idp.example.com"), new Uri("https://localhost/LoggedIn"), new Saml2Id("InResponseToId"), authProps.Items); var relayState = SecureKeyGenerator.CreateRelayState(); var cookieData = HttpRequestData.ConvertBinaryData( StubDataProtector.Protect(state.Serialize())); var cookieName = $"{StoredRequestState.CookieNameBase}{relayState}"; context.HttpContext.Request.Cookies = new StubCookieCollection( Enumerable.Repeat(new KeyValuePair <string, string>( cookieName, cookieData), 1)); var response = @"<saml2p:Response xmlns:saml2p=""urn:oasis:names:tc:SAML:2.0:protocol"" xmlns:saml2=""urn:oasis:names:tc:SAML:2.0:assertion"" ID = """ + MethodBase.GetCurrentMethod().Name + @""" Version=""2.0"" IssueInstant=""2013-01-01T00:00:00Z"" InResponseTo=""InResponseToId"" > <saml2:Issuer> https://idp.example.com </saml2:Issuer> <saml2p:Status> <saml2p:StatusCode Value=""urn:oasis:names:tc:SAML:2.0:status:Success"" /> </saml2p:Status> <saml2:Assertion Version=""2.0"" ID=""" + MethodBase.GetCurrentMethod().Name + @"_Assertion1"" IssueInstant=""2013-09-25T00:00:00Z""> <saml2:Issuer>https://idp.example.com</saml2:Issuer> <saml2:Subject> <saml2:NameID>SomeUser</saml2:NameID> <saml2:SubjectConfirmation Method=""urn:oasis:names:tc:SAML:2.0:cm:bearer"" /> </saml2:Subject> <saml2:Conditions NotOnOrAfter=""2100-01-01T00:00:00Z""> <saml2:AudienceRestriction> <saml2:Audience>http://sp.example.com/saml2</saml2:Audience> </saml2:AudienceRestriction> </saml2:Conditions> </saml2:Assertion> </saml2p:Response>"; var form = Substitute.For <IFormCollection>(); IEnumerator <KeyValuePair <string, StringValues> > formCollectionEnumerator = new KeyValuePair <string, StringValues>[] { new KeyValuePair <string, StringValues>( "SAMLResponse", new StringValues( Convert.ToBase64String( Encoding.UTF8.GetBytes(SignedXmlHelper.SignXml(response))))), new KeyValuePair <string, StringValues>( "RelayState", new StringValues(relayState)) }.AsEnumerable().GetEnumerator(); form.GetEnumerator().Returns(formCollectionEnumerator); context.HttpContext.Request.Form.Returns(form); var authService = Substitute.For <IAuthenticationService>(); context.HttpContext.RequestServices.GetService(typeof(IAuthenticationService)) .Returns(authService); ClaimsPrincipal principal = null; AuthenticationProperties actualAuthProps = null; await authService.SignInAsync( context.HttpContext, TestHelpers.defaultSignInScheme, Arg.Do <ClaimsPrincipal>(p => principal = p), Arg.Do <AuthenticationProperties>(ap => actualAuthProps = ap)); await context.Subject.HandleRequestAsync(); principal.HasClaim(ClaimTypes.NameIdentifier, "SomeUser").Should().BeTrue(); actualAuthProps.IssuedUtc.Should().Be(authProps.IssuedUtc); actualAuthProps.Items["Test"].Should().Be("TestValue"); context.HttpContext.Response.Headers["Location"].Single().Should().Be( state.ReturnUrl.OriginalString); context.HttpContext.Response.StatusCode.Should().Be(303); }
private HttpResponseData CheckRequestFailInsert(HttpRequestData r) { if (r.Path != "/query") { throw new Exception("Wrong path!"); } var response = new HttpResponseData(); if (r.Data == "{ token: \"77a5e3fad4d2646594fc12e67d2b6590e30df81f\", query: \"SELECT ?val FROM <https://carre.kmi.open.ac.uk/users/MindaugasB> WHERE { <https://carre.kmi.open.ac.uk/users/MindaugasB/measurements/vivaport_635688864000000000> <https://carre.kmi.open.ac.uk/users/MindaugasB/measurements/vivaport_635688864000000000_has_test1> ?val . }\" }") { response.StatusCode = System.Net.HttpStatusCode.OK; response.Data = "OK"; response.ContentLength = 1; } else { response.StatusCode = System.Net.HttpStatusCode.InternalServerError; } return response; }
private void VerifyVersionHeaders(HttpRequestData request) { #if !SILVERLIGHT || WIN8 if (request.Headers.Keys.Contains(HttpHeaders.Prefer)) { this.Assert.IsTrue(DataServiceProtocolVersion.V4 <= request.GetDataServiceVersion(), string.Format(CultureInfo.InvariantCulture, "Request DSV should be at least 3 if prefer is specified. Value was '{0}'.", request.Headers[HttpHeaders.DataServiceVersion])); this.Assert.IsTrue(DataServiceProtocolVersion.V4 <= request.GetMaxDataServiceVersion(), string.Format(CultureInfo.InvariantCulture, "Request MDSV should be at least 3 if prefer is specified. Value was '{0}'.", request.Headers[HttpHeaders.MaxDataServiceVersion])); } #endif }
private static void SetUnexpectedPreferHeader(HttpRequestData request) { request.Headers[HttpHeaders.Prefer] = null; }
private static void SetExpectedIfMatchHeader(HttpRequestData request, string etag) { // NOTE: we intentionally set this to null if the etag is null, because null means it was not included request.Headers[HttpHeaders.IfMatch] = etag; }
private static void SetExpectedMaxDataServiceVersion(HttpRequestData request, DSClient.DataServiceContext context) { DataServiceProtocolVersion maxDataServiceVersion = context.MaxProtocolVersion.ToTestEnum(); SetExpectedMaxDataServiceVersion(request, maxDataServiceVersion); }
private static void SetExpectedMaxDataServiceVersion(HttpRequestData request, DataServiceProtocolVersion maxDataServiceVersion) { request.Headers[HttpHeaders.MaxDataServiceVersion] = maxDataServiceVersion.ConvertToHeaderFormat() + ";" + HttpHeaders.NetFx; }
private void DoReceive() { byte[] buffer = receiveResult.Buffer; int offset = receiveResult.Offset; int count = receiveResult.Count; if (currentRequest == null && requestMessages.Count > 0) { currentRequest = new HttpRequestData(requestMessages[0]); requestMessages.RemoveAt(0); } if (totalExpected == 0) { if (webRequests.Count == 0) { sendResult.Complete(sendResult.Count); } else { KeyValuePair <WebRequest, int> r = webRequests.Dequeue(); totalExpected = r.Value; BeginGetResponse(r.Key, getResponseCallback, r.Key); } return; } if (!currentRequest.SentLength) { // The message length counts as the first four bytes currentRequest.SentLength = true; currentRequest.TotalReceived += 4; Message.Write(receiveResult.Buffer, receiveResult.Offset, currentRequest.TotalToReceive - currentRequest.TotalReceived); receiveResult.Complete(4); return; } else if (!currentRequest.SentHeader) { currentRequest.SentHeader = true; // We have *only* written the messageLength to the stream // Now we need to write the rest of the PieceMessage header int written = 0; written += Message.Write(buffer, offset + written, PieceMessage.MessageId); written += Message.Write(buffer, offset + written, CurrentRequest.Request.PieceIndex); written += Message.Write(buffer, offset + written, CurrentRequest.Request.StartOffset); count -= written; offset += written; receiveResult.BytesTransferred += written; currentRequest.TotalReceived += written; } int received = dataStream.Read(buffer, offset, count); if (disposed) { return; } try { if (received == 0) { throw new WebException("No futher data is available"); } receiveResult.BytesTransferred += received; currentRequest.TotalReceived += received; // We've received everything for this piece, so null it out if (currentRequest.Complete) { currentRequest = null; } totalExpected -= received; receiveResult.Complete(); } catch (Exception ex) { receiveResult.Complete(ex); } finally { // If there are no more requests pending, complete the Send call if (currentRequest == null && requestMessages.Count == 0) { RequestCompleted(); } } }
internal static HttpRequestData CreateRequest(byte[] body, Encoding encoding) { var request = new HttpRequestData(); var statusLine = ReadLine(ref body, encoding); var statusSections = statusLine.Split(' '); ExceptionUtilities.Assert(statusSections.Length == 3, "Request status line was malformed: '{0}'", statusLine); request.Verb = (HttpVerb)Enum.Parse(typeof(HttpVerb), statusSections[0], true); request.Uri = new Uri(statusSections[1], UriKind.RelativeOrAbsolute); PopulateHeadersAndBody(request, body, encoding); return request; }
private void CompareRequest(ExpectedClientRequest expected, IHttpRequest actual) { this.parent.Assert.AreEqual(expected.Verb, actual.Verb, "Request verb did not match"); // The headers are quite different when using XmlHttp if (!this.contextData.UsesXmlHttpStack()) { this.CompareHeaders(expected.Headers, actual.Headers); } if (expected.Body == null) { int actualLength = 0; var actualBody = actual.GetRequestBody(); if (actualBody != null) { actualLength = actualBody.Length; } this.parent.Assert.AreEqual(0, actualLength, "Request should not have had a body"); } else { ODataPayloadElement actualPayload; if (expected.Body.ElementType == ODataPayloadElementType.EntityInstance) { actualPayload = actual.DeserializeAndCast<EntityInstance>(this.parent.FormatSelector); } else if (expected.Body.ElementType == ODataPayloadElementType.DeferredLink) { actualPayload = actual.DeserializeAndCast<DeferredLink>(this.parent.FormatSelector); } else { ExceptionUtilities.Assert(expected.Body.ElementType == ODataPayloadElementType.PrimitiveValue, "Expected payload element was neither an entity, a link, nor a stream"); actualPayload = new PrimitiveValue(null, actual.GetRequestBody()); } try { this.parent.PayloadComparer.Compare(expected.Body, actualPayload); } catch (TestFailedException e) { this.parent.Log.WriteLine(LogLevel.Error, "Expected client request payload did not match actual."); var strategy = this.parent.FormatSelector.GetStrategy(actual.GetHeaderValueIfExists(HttpHeaders.ContentType), null); var expectedBinary = strategy.GetSerializer().SerializeToBinary(expected.Body); this.parent.Log.WriteLine(LogLevel.Verbose, "Expected request:"); var expectedToLog = new HttpRequestData() { Verb = expected.Verb, Uri = expected.Uri, Body = expectedBinary }; expectedToLog.Headers.AddRange(expected.Headers); expectedToLog.WriteToLog(this.parent.Log, LogLevel.Verbose); this.parent.Log.WriteLine(LogLevel.Verbose, "Actual request:"); actual.WriteToLog(this.parent.Log, LogLevel.Verbose); // wrap to preserve call stack throw new AssertionFailedException("Expected client request payload did not match actual.", e); } } }
private static void SetExpectedPreferHeader(HttpRequestData request, DSClient.DataServiceContext contextData) { SetExpectedPreferHeader(request, contextData.AddAndUpdateResponsePreference.ToTestEnum()); }
private void DoReceive() { byte[] buffer = receiveResult.Buffer; int offset = receiveResult.Offset; int count = receiveResult.Count; if (currentRequest == null && requestMessages.Count > 0) { currentRequest = new HttpRequestData(requestMessages[0]); requestMessages.RemoveAt(0); } if (totalExpected == 0) { if (webRequests.Count == 0) { sendResult.Complete(sendResult.Count); } else { KeyValuePair<WebRequest, int> r = webRequests.Dequeue(); totalExpected = r.Value; BeginGetResponse(r.Key, getResponseCallback, r.Key); } return; } if (!currentRequest.SentLength) { // The message length counts as the first four bytes currentRequest.SentLength = true; currentRequest.TotalReceived += 4; Message.Write(receiveResult.Buffer, receiveResult.Offset, currentRequest.TotalToReceive - currentRequest.TotalReceived); receiveResult.Complete(4); return; } else if (!currentRequest.SentHeader) { currentRequest.SentHeader = true; // We have *only* written the messageLength to the stream // Now we need to write the rest of the PieceMessage header int written = 0; written += Message.Write(buffer, offset + written, PieceMessage.MessageId); written += Message.Write(buffer, offset + written, CurrentRequest.Request.PieceIndex); written += Message.Write(buffer, offset + written, CurrentRequest.Request.StartOffset); count -= written; offset += written; receiveResult.BytesTransferred += written; currentRequest.TotalReceived += written; } int received = dataStream.Read(buffer, offset, count); if (disposed) return; try { if (received == 0) throw new WebException("No futher data is available"); receiveResult.BytesTransferred += received; currentRequest.TotalReceived += received; // We've received everything for this piece, so null it out if (currentRequest.Complete) currentRequest = null; totalExpected -= received; receiveResult.Complete(); } catch (Exception ex) { receiveResult.Complete(ex); } finally { // If there are no more requests pending, complete the Send call if (currentRequest == null && requestMessages.Count == 0) RequestCompleted(); } }
internal static async Task HandleAuthenticationRequest(LoopbackServer.Connection connection, bool useNtlm, bool useNegotiate, bool closeConnection) { HttpRequestData request = await connection.ReadRequestDataAsync(); NTAuthentication authContext = null; string authHeader = null; foreach (HttpHeaderData header in request.Headers) { if (header.Name == "Authorization") { authHeader = header.Value; break; } } if (string.IsNullOrEmpty(authHeader)) { // This is initial request, we reject with showing supported mechanisms. authHeader = string.Empty; if (useNtlm) { authHeader += NtlmAuthHeader + "\r\n"; } if (useNegotiate) { authHeader += NegotiateAuthHeader + "\r\n"; } await connection.SendResponseAsync(HttpStatusCode.Unauthorized, authHeader).ConfigureAwait(false); connection.CompleteRequestProcessing(); // Read next requests and fall-back to loop bellow to process it. request = await connection.ReadRequestDataAsync(); } SecurityStatusPal statusCode; do { foreach (HttpHeaderData header in request.Headers) { if (header.Name == "Authorization") { authHeader = header.Value; break; } } Assert.NotNull(authHeader); var tokens = authHeader.Split(' ', 2, StringSplitOptions.TrimEntries); // Should be type and base64 encoded blob Assert.Equal(2, tokens.Length); authContext ??= new NTAuthentication(isServer: true, tokens[0], CredentialCache.DefaultNetworkCredentials, null, ContextFlagsPal.Connection, null); byte[]? outBlob = authContext.GetOutgoingBlob(Convert.FromBase64String(tokens[1]), throwOnError: false, out statusCode); if (outBlob != null && statusCode.ErrorCode == SecurityStatusPalErrorCode.ContinueNeeded) { authHeader = $"WWW-Authenticate: {tokens[0]} {Convert.ToBase64String(outBlob)}\r\n"; await connection.SendResponseAsync(HttpStatusCode.Unauthorized, authHeader); connection.CompleteRequestProcessing(); request = await connection.ReadRequestDataAsync(); } }while (statusCode.ErrorCode == SecurityStatusPalErrorCode.ContinueNeeded); if (statusCode.ErrorCode == SecurityStatusPalErrorCode.OK) { // If authentication succeeded ask Windows about the identity and send it back as custom header. SecurityContextTokenHandle?userContext = null; using SafeDeleteContext securityContext = authContext.GetContext(out SecurityStatusPal statusCodeNew) !; SSPIWrapper.QuerySecurityContextToken(GlobalSSPI.SSPIAuth, securityContext, out userContext); using WindowsIdentity identity = new WindowsIdentity(userContext.DangerousGetHandle(), authContext.ProtocolName); authHeader = $"{UserHeaderName}: {identity.Name}\r\n"; if (closeConnection) { authHeader += "Connection: close\r\n"; } await connection.SendResponseAsync(HttpStatusCode.OK, authHeader, "foo"); userContext.Dispose(); } else { await connection.SendResponseAsync(HttpStatusCode.Forbidden, "Connection: close\r\n", "boo"); } }
public async Task <HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req) { logger.LogInformation("CreateSite function starting..."); // Parse the url parameters NameValueCollection parameters = HttpUtility.ParseQueryString(req.Url.Query); var siteName = parameters["siteName"]; var owner = parameters["owner"]; HttpResponseData response = null; try { using (var pnpContext = await contextFactory.CreateAsync("Default")) { response = req.CreateResponse(HttpStatusCode.OK); response.Headers.Add("Content-Type", "application/json"); var communicationSiteToCreate = new CommunicationSiteOptions(new Uri($"https://{pnpContext.Uri.DnsSafeHost}/sites/{siteName}"), "Demo site") { Description = "PnP Core SDK demo site", Language = Language.English, Owner = $"i:0#.f|membership|{owner}" }; logger.LogInformation($"Creating site: {communicationSiteToCreate.Url}"); // Create the new site collection using (var newSiteContext = await pnpContext.GetSiteCollectionManager().CreateSiteCollectionAsync(communicationSiteToCreate)) { logger.LogInformation($"Site created: {communicationSiteToCreate.Url}"); // Step 1: Upload image to site assets library var siteAssetsLibrary = await newSiteContext.Web.Lists.EnsureSiteAssetsLibraryAsync(p => p.RootFolder); var uploadFolder = await siteAssetsLibrary.RootFolder.EnsureFolderAsync("SitePages/PnP"); var addedFile = await uploadFolder.Files.AddAsync("parker.png", File.OpenRead($".{Path.DirectorySeparatorChar}parker.png"), true); // Step 2: Create the page var page = await newSiteContext.Web.NewPageAsync(); page.AddSection(CanvasSectionTemplate.OneColumn, 1); // Add text with inline image var text = page.NewTextPart(); var parker = await page.GetInlineImageAsync(text, addedFile.ServerRelativeUrl, new PageImageOptions { Alignment = PageImageAlignment.Left }); text.Text = $"<H2>Hello everyone!</H2>{parker}<P>Community rocks, sharing is caring!</P>"; page.AddControl(text, page.Sections[0].Columns[0]); // Save the page await page.SaveAsync("PnP.aspx"); // Return the URL of the created site await response.WriteStringAsync(JsonSerializer.Serialize(new { siteUrl = newSiteContext.Uri.AbsoluteUri })); } return(response); } } catch (Exception ex) { response = req.CreateResponse(HttpStatusCode.OK); response.Headers.Add("Content-Type", "application/json"); await response.WriteStringAsync(JsonSerializer.Serialize(new { error = ex.Message })); return(response); } }
public void AuthServicesController_Acs_Works() { var request = Substitute.For <HttpRequestBase>(); request.HttpMethod.Returns("POST"); var response = @"<saml2p:Response xmlns:saml2p=""urn:oasis:names:tc:SAML:2.0:protocol"" xmlns:saml2=""urn:oasis:names:tc:SAML:2.0:assertion"" ID = """ + MethodBase.GetCurrentMethod().Name + @""" Version=""2.0"" IssueInstant=""2013-01-01T00:00:00Z"" InResponseTo=""InResponseToId""> <saml2:Issuer> https://idp.example.com </saml2:Issuer> <saml2p:Status> <saml2p:StatusCode Value=""urn:oasis:names:tc:SAML:2.0:status:Success"" /> </saml2p:Status> <saml2:Assertion Version=""2.0"" ID=""" + MethodBase.GetCurrentMethod().Name + @"_Assertion1"" IssueInstant=""2013-09-25T00:00:00Z""> <saml2:Issuer>https://idp.example.com</saml2:Issuer> <saml2:Subject> <saml2:NameID>SomeUser</saml2:NameID> <saml2:SubjectConfirmation Method=""urn:oasis:names:tc:SAML:2.0:cm:bearer"" /> </saml2:Subject> <saml2:Conditions NotOnOrAfter=""2100-01-01T00:00:00Z"" /> </saml2:Assertion> </saml2p:Response>"; var formValue = Convert.ToBase64String(Encoding.UTF8.GetBytes( SignedXmlHelper.SignXml(response))); var relayState = "rs1234"; request.Form.Returns(new NameValueCollection() { { "SAMLResponse", formValue }, { "RelayState", relayState } }); request.Url.Returns(new Uri("http://url.example.com/url")); request.Cookies.Returns(new HttpCookieCollection()); request.Cookies.Add(new HttpCookie("Kentor." + relayState, HttpRequestData.ConvertBinaryData( MachineKey.Protect( new StoredRequestState(null, null, new Saml2Id("InResponseToId"), null).Serialize(), HttpRequestBaseExtensions.ProtectionPurpose)))); var httpContext = Substitute.For <HttpContextBase>(); httpContext.Request.Returns(request); var controller = new AuthServicesController(); controller.ControllerContext = new ControllerContext(httpContext, new RouteData(), controller); var expected = new { Permanent = false, Url = "http://localhost/LoggedIn" }; controller.Acs().As <RedirectResult>().ShouldBeEquivalentTo(expected); controller.Response.Received().SetCookie( Arg.Is <HttpCookie>(c => c.Expires.Year == 1970)); }
private HttpResponseData CheckRequestSuccessInsert(HttpRequestData r) { if (r.Path != "/query") { throw new Exception("Wrong path!"); } var response = new HttpResponseData(); if (r.Data.Contains("token: \"77a5e3fad4d2646594fc12e67d2b6590e30df81f\"")) { if (r.Data.Contains("query: \"SELECT ?val FROM <https://carre.kmi.open.ac.uk/users/MindaugasB> WHERE { <https://carre.kmi.open.ac.uk/users/MindaugasB/measurements/vivaport_635692320000000000>")) { response.StatusCode = System.Net.HttpStatusCode.OK; } if (r.Data.Contains("query: \"INSERT DATA { GRAPH <https://carre.kmi.open.ac.uk/users/MindaugasB> { <https://carre.kmi.open.ac.uk/users/MindaugasB/measurements/vivaport_635692320000000000> <http://www.w3.org/2000/01/rdf-schema#type> :individual_test1_measurement .\n")) { response.StatusCode = System.Net.HttpStatusCode.OK; response.Data = "OK"; response.ContentLength = 1; } } else { response.StatusCode = System.Net.HttpStatusCode.InternalServerError; } return response; }
private byte[] DecryptCookieData(string data) { return(MachineKey.Unprotect( HttpRequestData.GetBinaryData(data), "Sustainsys.Saml2")); }
public async Task Saml2Handler_SignOutAsync_InitiatesSignOutIfConfigured() { var context = new Saml2HandlerTestContext(); context.Subject.options.IdentityProviders.Default.SingleLogoutServiceUrl = new Uri("https://idp.example.com/Logout"); context.Subject.options.SPOptions.ServiceCertificates.Add(new X509Certificate2("Sustainsys.Saml2.Tests.pfx")); context.HttpContext.User = new ClaimsPrincipal( new ClaimsIdentity(new Claim[] { new Claim(Saml2ClaimTypes.LogoutNameIdentifier, ",,,,NameId", null, "https://idp.example.com"), new Claim(Saml2ClaimTypes.SessionIndex, "SessionId", null, "https://idp.example.com") }, "Federation")); IAuthenticationSignOutHandler subject = context.Subject; var props = new AuthenticationProperties() { RedirectUri = "/loggedout" }; await subject.SignOutAsync(props); context.HttpContext.Response.Body.Length.Should().Be(0, "when using redirect binding, nothing should be written to body"); context.HttpContext.Response.StatusCode.Should().Be(303, "when using redirect binding, status code shoulde be 303"); context.HttpContext.Response.Headers["Location"].Single().Should().StartWith("https://idp.example.com/Logout?SAMLRequest=", "location should be set for outbound redirect binding"); context.HttpContext.Response.Cookies.Received().Append( Arg.Is <string>(s => s.StartsWith(StoredRequestState.CookieNameBase)), Arg.Is <string>(s => new StoredRequestState(StubDataProtector.Unprotect(HttpRequestData.GetBinaryData(s))) .ReturnUrl.OriginalString == "/loggedout"), Arg.Any <CookieOptions>()); }
private void DoReceive() { var buffer = _receiveResult.Buffer; var offset = _receiveResult.Offset; var count = _receiveResult.Count; if (_currentRequest == null && _requestMessages.Count > 0) { _currentRequest = new HttpRequestData(_requestMessages[0]); _requestMessages.RemoveAt(0); } if (_totalExpected == 0) { if (_webRequests.Count == 0) { _sendResult.Complete(_sendResult.Count); } else { var r = _webRequests.Dequeue(); _totalExpected = r.Value; BeginGetResponse(r.Key, _getResponseCallback, r.Key); } return; } if (_currentRequest != null && !_currentRequest.SentLength) { // The message length counts as the first four bytes _currentRequest.SentLength = true; _currentRequest.TotalReceived += 4; Message.Write(_receiveResult.Buffer, _receiveResult.Offset, _currentRequest.TotalToReceive - _currentRequest.TotalReceived); _receiveResult.Complete(4); return; } if (_currentRequest != null && !_currentRequest.SentHeader) { _currentRequest.SentHeader = true; // We have *only* written the messageLength to the stream // Now we need to write the rest of the PieceMessage header var written = 0; written += Message.Write(buffer, offset + written, PieceMessage.MessageId); written += Message.Write(buffer, offset + written, _currentRequest.Request.PieceIndex); written += Message.Write(buffer, offset + written, _currentRequest.Request.StartOffset); count -= written; offset += written; _receiveResult.BytesTransferred += written; _currentRequest.TotalReceived += written; } _dataStream.ReadAsync(buffer, offset, count).ContinueWith(p => _receivedChunkCallback(p)); }
public void LogoutCommand_Run_ReturnsLogoutRequest() { var user = new ClaimsPrincipal( new ClaimsIdentity(new Claim[] { new Claim(Saml2ClaimTypes.LogoutNameIdentifier, ",,,,NameId", null, "https://idp.example.com"), new Claim(Saml2ClaimTypes.SessionIndex, "SessionId", null, "https://idp.example.com") }, "Federation")); var request = new HttpRequestData("GET", new Uri("http://sp-internal.example.com/Saml2/Logout")) { User = user }; var options = StubFactory.CreateOptions(); options.SPOptions.ServiceCertificates.Add(SignedXmlHelper.TestCert); options.SPOptions.PublicOrigin = new Uri("https://sp.example.com/"); CommandResult notifiedCommandResult = null; options.Notifications.LogoutCommandResultCreated = cr => { notifiedCommandResult = cr; }; Saml2LogoutRequest logoutRequest = null; options.Notifications.LogoutRequestCreated = (lr, u, idp) => { logoutRequest = lr; u.Identities.Single().FindFirst(Saml2ClaimTypes.SessionIndex).Value.Should().Be("SessionId"); idp.EntityId.Id.Should().Be("https://idp.example.com"); }; var logoutRequestXmlCreatedCalled = false; options.Notifications.LogoutRequestXmlCreated = (lr, xd, bt) => { logoutRequestXmlCreatedCalled = true; xd.Root.Attribute("ID").Value.Should().Be(lr.Id.Value); bt.Should().Be(Saml2BindingType.HttpRedirect); }; var actual = CommandFactory.GetCommand(CommandFactory.LogoutCommandName) .Run(request, options); actual.Should().BeSameAs(notifiedCommandResult); logoutRequest.Should().NotBeNull(); logoutRequestXmlCreatedCalled.Should().BeTrue(); var expected = new CommandResult { HttpStatusCode = HttpStatusCode.SeeOther, TerminateLocalSession = true, // Deliberately not comparing Location. // Deliberately not comparing SetCookieName. RequestState = new StoredRequestState( new EntityId("https://idp.example.com"), new Uri("https://sp.example.com/"), null, null), SetCookieSecureFlag = true }; actual.Should().BeEquivalentTo(expected, opt => opt .Excluding(cr => cr.Location) .Excluding(cr => cr.SetCookieName) .Excluding(cr => cr.RelayState) .Excluding(cr => cr.RequestState.MessageId)); var relayState = HttpUtility.ParseQueryString(actual.Location.Query)["RelayState"]; actual.SetCookieName.Should().Be(StoredRequestState.CookieNameBase + relayState); actual.RelayState.Should().Be(relayState); actual.Location.GetLeftPart(UriPartial.Path).Should().Be("https://idp.example.com/logout"); }
public void AcsCommand_Run_WithReturnUrl_SuccessfulResult() { var idp = Options.FromConfiguration.IdentityProviders.Default; var response = @"<saml2p:Response xmlns:saml2p=""urn:oasis:names:tc:SAML:2.0:protocol"" xmlns:saml2=""urn:oasis:names:tc:SAML:2.0:assertion"" ID = """ + MethodBase.GetCurrentMethod().Name + @""" InResponseTo = ""InResponseToId"" Version=""2.0"" IssueInstant=""2013-01-01T00:00:00Z""> <saml2:Issuer> https://idp.example.com </saml2:Issuer> <saml2p:Status> <saml2p:StatusCode Value=""urn:oasis:names:tc:SAML:2.0:status:Success"" /> </saml2p:Status> <saml2:Assertion Version=""2.0"" ID=""" + MethodBase.GetCurrentMethod().Name + @"_Assertion2"" IssueInstant=""2013-09-25T00:00:00Z""> <saml2:Issuer>https://idp.example.com</saml2:Issuer> <saml2:Subject> <saml2:NameID>SomeUser</saml2:NameID> <saml2:SubjectConfirmation Method=""urn:oasis:names:tc:SAML:2.0:cm:bearer"" /> </saml2:Subject> <saml2:Conditions NotOnOrAfter=""2100-01-01T00:00:00Z"" /> </saml2:Assertion> </saml2p:Response>"; var responseFormValue = Convert.ToBase64String (Encoding.UTF8.GetBytes(SignedXmlHelper.SignXml(response))); var relayStateFormValue = "rs1234"; var r = new HttpRequestData( "POST", new Uri("http://localhost"), "/ModulePath", new KeyValuePair <string, IEnumerable <string> >[] { new KeyValuePair <string, IEnumerable <string> >("SAMLResponse", new string[] { responseFormValue }), new KeyValuePair <string, IEnumerable <string> >("RelayState", new string[] { relayStateFormValue }) }, new StoredRequestState( new EntityId("https://idp.example.com"), new Uri("http://localhost/testUrl.aspx"), new Saml2Id("InResponseToId"), null) ); var ids = new ClaimsIdentity[] { new ClaimsIdentity("Federation") }; ids[0].AddClaim(new Claim(ClaimTypes.NameIdentifier, "SomeUser", null, "https://idp.example.com")); var expected = new CommandResult() { Principal = new ClaimsPrincipal(ids), HttpStatusCode = HttpStatusCode.SeeOther, Location = new Uri("http://localhost/testUrl.aspx"), ClearCookieName = StoredRequestState.CookieNameBase + relayStateFormValue }; new AcsCommand().Run(r, StubFactory.CreateOptions()) .Should().BeEquivalentTo(expected, opt => opt.IgnoringCyclicReferences()); }
public static async Task <HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req, FunctionContext executionContext) { var log = executionContext.GetLogger("CreateEmptyAsset"); log.LogInformation("C# HTTP trigger function processed a request."); // Get request body data. string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); var data = (RequestBodyModel)JsonConvert.DeserializeObject(requestBody, typeof(RequestBodyModel)); // Return bad request if input asset name is not passed in if (data.AssetNamePrefix == null) { return(HttpRequest.ResponseBadRequest(req, "Please pass assetNamePrefix in the request body")); } ConfigWrapper config = ConfigUtils.GetConfig(); IAzureMediaServicesClient client; try { client = await Authentication.CreateMediaServicesClientAsync(config); log.LogInformation("AMS Client created."); } catch (Exception e) { if (e.Source.Contains("ActiveDirectory")) { log.LogError("TIP: Make sure that you have filled out the appsettings.json file before running this sample."); } log.LogError($"{e.Message}"); return(HttpRequest.ResponseBadRequest(req, e.Message)); } // Set the polling interval for long running operations to 2 seconds. // The default value is 30 seconds for the .NET client SDK client.LongRunningOperationRetryTimeout = 2; // Creating a unique suffix so that we don't have name collisions if you run the sample // multiple times without cleaning up. string uniqueness = Guid.NewGuid().ToString().Substring(0, 13); string assetName = $"{data.AssetNamePrefix}-{uniqueness}"; Asset asset; try { // let's create the asset asset = await AssetUtils.CreateAssetAsync(client, log, config.ResourceGroup, config.AccountName, assetName, data.AssetStorageAccount, data.AssetDescription); log.LogInformation($"Asset '{assetName}' created."); } catch (ErrorResponseException ex) { return(HttpRequest.ResponseBadRequest(req, LogUtils.LogError(log, ex, "Error when creating the asset."))); } try { // let's get the asset to have full metadata like container asset = await client.Assets.GetAsync(config.ResourceGroup, config.AccountName, assetName); } catch (ErrorResponseException ex) { return(HttpRequest.ResponseBadRequest(req, LogUtils.LogError(log, ex, "Error when getting the created asset."))); } AnswerBodyModel dataOk = new() { AssetName = asset.Name, AssetId = asset.AssetId, Container = asset.Container }; return(HttpRequest.ResponseOk(req, dataOk, HttpStatusCode.Created)); } }
public void Saml2Binding_Get_NullOnPostWithSamlartQuery() { var r = new HttpRequestData("POST", new Uri("http://example.com?Samlart=foo")); Saml2Binding.Get(r).Should().BeNull(); }
public void AcsCommand_Run_UsesIdpFromNotification() { var messageId = MethodBase.GetCurrentMethod().Name; var response = $@"<saml2p:Response xmlns:saml2p=""urn:oasis:names:tc:SAML:2.0:protocol"" xmlns:saml2=""urn:oasis:names:tc:SAML:2.0:assertion"" ID = ""{messageId}"" Version=""2.0"" InResponseTo=""InResponseToID"" IssueInstant=""2013-01-01T00:00:00Z""> <saml2:Issuer> https://other.idp.example.com </saml2:Issuer> <saml2p:Status> <saml2p:StatusCode Value=""urn:oasis:names:tc:SAML:2.0:status:Success"" /> </saml2p:Status> <saml2:Assertion Version=""2.0"" ID=""{messageId}_Assertion"" IssueInstant=""2013-09-25T00:00:00Z""> <saml2:Issuer>https://other.idp.example.com</saml2:Issuer> <saml2:Subject> <saml2:NameID>SomeUser</saml2:NameID> <saml2:SubjectConfirmation Method=""urn:oasis:names:tc:SAML:2.0:cm:bearer"" /> </saml2:Subject> <saml2:Conditions NotOnOrAfter=""2100-01-01T00:00:00Z"" /> <saml2:AuthnStatement AuthnInstant=""{DateTime.UtcNow.ToSaml2DateTimeString()}""> <saml2:AuthnContext> <saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef> </saml2:AuthnContext> </saml2:AuthnStatement> </saml2:Assertion> </saml2p:Response>"; var formValue = Convert.ToBase64String(Encoding.UTF8.GetBytes( SignedXmlHelper.SignXml(response))); var relayData = new Dictionary <string, string> { { "key", "value" } }; var requestData = new HttpRequestData( "POST", new Uri("http://localhost"), "/ModulePath", new KeyValuePair <string, IEnumerable <string> >[] { new KeyValuePair <string, IEnumerable <string> >("SAMLResponse", new string[] { formValue }) }, new StoredRequestState( new EntityId("https://other.idp.example.com"), new Uri("http://localhost/testUrl.aspx"), new Saml2Id("InResponseToID"), relayData)); var options = StubFactory.CreateOptions(); options.Notifications.GetIdentityProvider = (idpEntityId, rd, opt) => { idpEntityId.Id.Should().Be("https://other.idp.example.com"); rd["key"].Should().Be("value"); var idp = new IdentityProvider(new EntityId("https://other.idp.example.com"), options.SPOptions); idp.SigningKeys.AddConfiguredKey(SignedXmlHelper.TestCert); return(idp); }; var subject = new AcsCommand(); var actual = subject.Run(requestData, options); actual.Principal.Claims.First().Issuer.Should().Be("https://other.idp.example.com"); }
protected internal override bool CanUnbind(HttpRequestData request) { throw new NotImplementedException(); }
public Task <HttpResponseData> Http([HttpTrigger(AuthorizationLevel.Admin, "get", "Post", Route = "/api2")] HttpRequestData myReq) { throw new NotImplementedException(); }
static void stressTester_RequestProcessed(HttpRequestData req ) { string output = req.StatusCode + " - " + req.HttpVerb + " " + req.Url + "(" + req.TimeTakenMs.ToString("n0") + "ms)"; lock (consoleLock) { if (req.IsError) Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(output); if (req.IsError) Console.ForegroundColor = ConsoleColor.Green; } }
public void AcsCommand_Run_CallsNotifications() { var messageId = MethodBase.GetCurrentMethod().Name; var response = @"<saml2p:Response xmlns:saml2p=""urn:oasis:names:tc:SAML:2.0:protocol"" xmlns:saml2=""urn:oasis:names:tc:SAML:2.0:assertion"" ID = """ + messageId + @""" Version=""2.0"" IssueInstant=""2013-01-01T00:00:00Z""> <saml2:Issuer> https://idp.example.com </saml2:Issuer> <saml2p:Status> <saml2p:StatusCode Value=""urn:oasis:names:tc:SAML:2.0:status:Success"" /> </saml2p:Status> <saml2:Assertion Version=""2.0"" ID=""" + messageId + @"_Assertion"" IssueInstant=""2013-09-25T00:00:00Z""> <saml2:Issuer>https://idp.example.com</saml2:Issuer> <saml2:Subject> <saml2:NameID>SomeUser</saml2:NameID> <saml2:SubjectConfirmation Method=""urn:oasis:names:tc:SAML:2.0:cm:bearer"" /> </saml2:Subject> <saml2:Conditions NotOnOrAfter=""2100-01-01T00:00:00Z"" /> </saml2:Assertion> </saml2p:Response>"; var formValue = Convert.ToBase64String(Encoding.UTF8.GetBytes( SignedXmlHelper.SignXml(response))); var requestData = new HttpRequestData( "POST", new Uri("http://localhost"), "/ModulePath", new KeyValuePair <string, IEnumerable <string> >[] { new KeyValuePair <string, IEnumerable <string> >("SAMLResponse", new string[] { formValue }) }, null); var options = StubFactory.CreateOptions(); var responseUnboundCalled = false; options.Notifications.MessageUnbound = ur => { ur.Should().NotBeNull(); responseUnboundCalled = true; }; CommandResult notifiedCommandResult = null; options.Notifications.AcsCommandResultCreated = (cr, r) => { notifiedCommandResult = cr; r.Id.Value.Should().Be(messageId); }; new AcsCommand().Run(requestData, options) .Should().BeSameAs(notifiedCommandResult); responseUnboundCalled.Should().BeTrue("the ResponseUnbound notification should have been called."); }
private void DoReceive() { byte[] buffer = receiveResult.Buffer; int offset = receiveResult.Offset; int count = receiveResult.Count; if (currentRequest == null && requestMessages.Count > 0) { currentRequest = new HttpRequestData(requestMessages[0]); requestMessages.RemoveAt(0); } if (totalExpected == 0) { if (webRequests.Count == 0) { sendResult.Complete(sendResult.Count); } else { KeyValuePair<WebRequest, int> r = webRequests.Dequeue(); totalExpected = r.Value; BeginGetResponse(r.Key, getResponseCallback, r.Key); } return; } if (!currentRequest.SentLength) { // The message length counts as the first four bytes currentRequest.SentLength = true; currentRequest.TotalReceived += 4; Message.Write(receiveResult.Buffer, receiveResult.Offset, currentRequest.TotalToReceive - currentRequest.TotalReceived); receiveResult.Complete(4); return; } else if (!currentRequest.SentHeader) { currentRequest.SentHeader = true; // We have *only* written the messageLength to the stream // Now we need to write the rest of the PieceMessage header int written = 0; written += Message.Write(buffer, offset + written, PieceMessage.MessageId); written += Message.Write(buffer, offset + written, CurrentRequest.Request.PieceIndex); written += Message.Write(buffer, offset + written, CurrentRequest.Request.StartOffset); count -= written; offset += written; receiveResult.BytesTransferred += written; currentRequest.TotalReceived += written; } dataStream.BeginRead(buffer, offset, count, receivedChunkCallback, null); }
public void Saml2Binding_Get_NullOnPlainPost() { var r = new HttpRequestData("POST", new Uri("http://example.com")); Saml2Binding.Get(r).Should().BeNull(); }
public HttpRequest(string url, HttpRequestData data) : this(url, null, data, null) { }
/// <summary> /// Handles the request/response pair /// </summary> /// <param name="context">The context making the request</param> /// <param name="request">The http request</param> /// <param name="response">The http response</param> internal void HandleRequestResponsePair(DataServiceContext context, HttpRequestData request, HttpResponseData response) { ExceptionUtilities.CheckArgumentNotNull(context, "context"); ExceptionUtilities.CheckArgumentNotNull(request, "request"); ExceptionUtilities.CheckArgumentNotNull(response, "response"); this.assert.AreSame(this.expectedContext, context, "Test hook fired by unexpected context"); // verify request uri this.assert.IsNotNull(this.uriFromEvent, "Uri from event unexpectely null. Sending request event did not fire"); this.assert.AreEqual(this.uriFromEvent, request.Uri, "Uri on wire did not match uri from SendingRequest event."); this.uriFromEvent = null; // verify request verb this.assert.IsNotNull(this.methodFromEvent, "Method from event unexpectely null. Sending request event did not fire"); bool usingXmlHttpStack = false; string expectedMethod = request.Verb.ToHttpMethod(); if (request.Headers.ContainsKey("X-HTTP-Method")) { expectedMethod = request.Headers["X-HTTP-Method"]; } this.assert.AreEqual(this.methodFromEvent.ToUpperInvariant(), expectedMethod.ToUpperInvariant(), "Method on wire did not match verb from SendingRequest event."); this.methodFromEvent = null; // Not validating headers on XmlHttpRequests as these will fail if (!usingXmlHttpStack) { // verify request headers this.VerifyHeaders(request.Headers); } }
public void RequestWork(object state) { try { #if NETFX_CORE System.Net.HttpWebRequest req = System.Net.HttpWebRequest.CreateHttp(new Uri(_Url)); #else #if (UNITY_5 || UNITY_5_3_OR_NEWER) System.Net.HttpWebRequest req = System.Net.HttpWebRequest.Create(new Uri(_Url)) as System.Net.HttpWebRequest; #else System.Net.HttpWebRequest req = new System.Net.HttpWebRequest(new Uri(_Url)); #endif req.KeepAlive = false; #endif try { lock (_CloseLock) { if (_Closed) { #if !HTTP_REQ_DONOT_ABORT req.Abort(); #endif if (_Status != RequestStatus.Finished) { _Error = "Request Error (Cancelled)"; _Status = RequestStatus.Finished; } return; } _InnerReq = req; } #if !NETFX_CORE req.Timeout = int.MaxValue; req.ReadWriteTimeout = int.MaxValue; #if !HTTP_REQ_DONOT_ABORT if (_Timeout > 0) { req.Timeout = _Timeout; req.ReadWriteTimeout = _Timeout; } #endif #endif if (_Headers != null) { foreach (var kvp in _Headers.Data) { var key = kvp.Key; var val = (kvp.Value ?? "").ToString(); if (key.IndexOfAny(new[] { '\r', '\n', ':', }) >= 0) { continue; // it is dangerous, may be attacking. } if (val.IndexOfAny(new[] { '\r', '\n', }) >= 0) { continue; // it is dangerous, may be attacking. } else { req.Headers[key] = val; } } } if (_RangeEnabled) { long filepos = 0; if (_Dest != null) { using (var stream = PlatExt.PlatDependant.OpenRead(_Dest)) { if (stream != null) { try { filepos = stream.Length; } catch (Exception e) { if (GLog.IsLogErrorEnabled) { GLog.LogException(e); } } } } } if (filepos <= 0) { if (_DestStream != null) { try { if (_DestStream.CanSeek) { filepos = _DestStream.Length; } } catch (Exception e) { if (GLog.IsLogErrorEnabled) { GLog.LogException(e); } } } } if (filepos > 0) { if (filepos > int.MaxValue) { _RangeEnabled = false; } else { req.AddRange((int)filepos); } } else { _RangeEnabled = false; } } if (_Data != null && (_Data.Count > 0 || _Data.Encoded != null)) { req.Method = "POST"; var data = _Data.Encoded; if (data == null) { req.ContentType = _Data.ContentType; data = _Data.Encode(); } else { req.ContentType = "application/octet-stream"; } #if NETFX_CORE var tstream = req.GetRequestStreamAsync(); if (_Timeout > 0) { if (!tstream.Wait(_Timeout)) { throw new TimeoutException(); } } else { tstream.Wait(); } var stream = tstream.Result; #else req.ContentLength = data.Length; var stream = req.GetRequestStream(); #endif lock (_CloseLock) { if (_Closed) { #if !HTTP_REQ_DONOT_ABORT req.Abort(); #endif if (_Status != RequestStatus.Finished) { _Error = "Request Error (Cancelled)"; _Status = RequestStatus.Finished; } return; } } if (stream != null) { #if NETFX_CORE if (_Timeout > 0) { stream.WriteTimeout = _Timeout; } else { stream.WriteTimeout = int.MaxValue; } #endif try { stream.Write(data, 0, data.Length); stream.Flush(); } finally { stream.Dispose(); } } } else { } lock (_CloseLock) { if (_Closed) { #if !HTTP_REQ_DONOT_ABORT req.Abort(); #endif if (_Status != RequestStatus.Finished) { _Error = "Request Error (Cancelled)"; _Status = RequestStatus.Finished; } return; } } #if NETFX_CORE var tresp = req.GetResponseAsync(); if (_Timeout > 0) { if (!tresp.Wait(_Timeout)) { throw new TimeoutException(); } } else { tresp.Wait(); } var resp = tresp.Result; #else var resp = req.GetResponse(); #endif lock (_CloseLock) { if (_Closed) { #if !HTTP_REQ_DONOT_ABORT req.Abort(); #endif if (_Status != RequestStatus.Finished) { _Error = "Request Error (Cancelled)"; _Status = RequestStatus.Finished; } return; } } if (resp != null) { try { _Total = (ulong)resp.ContentLength; } catch { } try { _RespHeaders = new HttpRequestData(); foreach (var key in resp.Headers.AllKeys) { _RespHeaders.Add(key, resp.Headers[key]); } if (_RangeEnabled) { bool rangeRespFound = false; foreach (var key in resp.Headers.AllKeys) { if (key.ToLower() == "content-range") { rangeRespFound = true; } } if (!rangeRespFound) { _RangeEnabled = false; } } var stream = resp.GetResponseStream(); lock (_CloseLock) { if (_Closed) { #if !HTTP_REQ_DONOT_ABORT req.Abort(); #endif if (_Status != RequestStatus.Finished) { _Error = "Request Error (Cancelled)"; _Status = RequestStatus.Finished; } return; } } if (stream != null) { #if NETFX_CORE if (_Timeout > 0) { stream.ReadTimeout = _Timeout; } else { stream.ReadTimeout = int.MaxValue; } #endif Stream streamd = null; try { byte[] buffer = new byte[1024 * 1024]; ulong totalcnt = 0; int readcnt = 0; bool mem = false; if (_Dest != null) { if (_RangeEnabled) { streamd = Capstones.PlatExt.PlatDependant.OpenAppend(_Dest); totalcnt = (ulong)streamd.Length; } else { streamd = Capstones.PlatExt.PlatDependant.OpenWrite(_Dest); } #if HTTP_REQ_DONOT_ABORT if (streamd != null) { _CloseList.Add(streamd); } #endif } if (streamd == null) { if (_DestStream != null) { if (_RangeEnabled) { _DestStream.Seek(0, SeekOrigin.End); totalcnt = (ulong)_DestStream.Length; } streamd = _DestStream; } else { mem = true; streamd = new MemoryStream(); #if HTTP_REQ_DONOT_ABORT _CloseList.Add(streamd); #endif } } if (_Total > 0) { _Total += totalcnt; } do { lock (_CloseLock) { if (_Closed) { #if !HTTP_REQ_DONOT_ABORT req.Abort(); #endif if (_Status != RequestStatus.Finished) { _Error = "Request Error (Cancelled)"; _Status = RequestStatus.Finished; } return; } } try { readcnt = 0; readcnt = stream.Read(buffer, 0, 1024 * 1024); if (readcnt <= 0) { stream.ReadByte(); // when it is closed, we need read to raise exception. break; } streamd.Write(buffer, 0, readcnt); streamd.Flush(); } catch (TimeoutException te) { if (GLog.IsLogErrorEnabled) { GLog.LogException(te); } _Error = "timedout"; } catch (System.Net.WebException we) { if (GLog.IsLogErrorEnabled) { GLog.LogException(we); } #if NETFX_CORE if (we.Status.ToString() == "Timeout") #else if (we.Status == System.Net.WebExceptionStatus.Timeout) #endif { _Error = "timedout"; } else { _Error = "Request Error (Exception):\n" + we.ToString(); } } catch (Exception e) { if (GLog.IsLogErrorEnabled) { GLog.LogException(e); } _Error = "Request Error (Exception):\n" + e.ToString(); } lock (_CloseLock) { if (_Closed) { #if !HTTP_REQ_DONOT_ABORT req.Abort(); #endif if (_Status != RequestStatus.Finished) { _Error = "Request Error (Cancelled)"; _Status = RequestStatus.Finished; } return; } } totalcnt += (ulong)readcnt; _Length = totalcnt; //Capstones.PlatExt.PlatDependant.LogInfo(readcnt); } while (readcnt > 0); if (mem) { _Resp = ((MemoryStream)streamd).ToArray(); } } finally { stream.Dispose(); if (streamd != null) { if (streamd != _DestStream) { streamd.Dispose(); } } } } } finally { #if NETFX_CORE resp.Dispose(); #else resp.Close(); #endif } } } catch (TimeoutException te) { if (GLog.IsLogErrorEnabled) { GLog.LogException(te); } _Error = "timedout"; } catch (System.Net.WebException we) { if (GLog.IsLogErrorEnabled) { GLog.LogException(we); } #if NETFX_CORE if (we.Status.ToString() == "Timeout") #else if (we.Status == System.Net.WebExceptionStatus.Timeout) #endif { _Error = "timedout"; } else { if (we.Response is System.Net.HttpWebResponse && ((System.Net.HttpWebResponse)we.Response).StatusCode == System.Net.HttpStatusCode.RequestedRangeNotSatisfiable) { } else { _Error = "Request Error (Exception):\n" + we.ToString(); } } } catch (Exception e) { if (GLog.IsLogErrorEnabled) { GLog.LogException(e); } _Error = "Request Error (Exception):\n" + e.ToString(); } finally { if (_Error == null) { lock (_CloseLock) { _Closed = true; _InnerReq = null; } } else { StopRequest(); } } } catch (TimeoutException te) { if (GLog.IsLogErrorEnabled) { GLog.LogException(te); } _Error = "timedout"; } catch (System.Net.WebException we) { if (GLog.IsLogErrorEnabled) { GLog.LogException(we); } #if NETFX_CORE if (we.Status.ToString() == "Timeout") #else if (we.Status == System.Net.WebExceptionStatus.Timeout) #endif { _Error = "timedout"; } else { _Error = "Request Error (Exception):\n" + we.ToString(); } } catch (Exception e) { if (GLog.IsLogErrorEnabled) { GLog.LogException(e); } _Error = "Request Error (Exception):\n" + e.ToString(); } finally { lock (_CloseLock) { _Status = RequestStatus.Finished; if (_OnDone != null) { var ondone = _OnDone; _OnDone = null; ondone(); } } } }
public static async Task <HttpResponseData> RunAsync( [HttpTrigger(AuthorizationLevel.Anonymous, "put", Route = "users")] HttpRequestData req, UpdateUserDto data ) { // Create response var response = req.CreateResponse(); // Get user id var userId = Utils.GetUserId(req.Headers); // Validate params var valid = Validate(userId, data); if (valid.Item1) { try { // Get container var userContainer = await CosmosDb.GetContainerAsync(CosmosDb.USER_CONTAINER_ID); // Get item var query = new QueryDefinition(@$ "SELECT * FROM c WHERE c.id = @userId") .WithParameter("@userId", userId); var user = await CosmosDb.GetItemByQueryAsync <User>(userContainer, query); if (user != null && Utils.VerifyPassword(data.Password, user.Salt, user.Password)) { // Update item user.Name = data.Name; if (data.UpdatePassword) { user.Salt = Utils.GenerateSalt(); user.Password = Utils.HashPassword(data.NewPassword, user.Salt); } Task.WaitAll( // Save to database CosmosDb.UpdateItemAsync <User>(userContainer, user, user.Id.ToString(), user.Id.ToString()), // Response update successful response.WriteAsJsonAsync("Updated user").AsTask() ); } else { // Response not found message await response.WriteAsJsonAsync("Incorrect password"); } } catch (CosmosException ex) { // Response error message await response.WriteAsJsonAsync(ex.Message); // Set http status code response.StatusCode = (HttpStatusCode)ex.Status; } } else { // Response invalid await response.WriteAsJsonAsync(valid.Item2); // Set http status code response.StatusCode = HttpStatusCode.BadRequest; } return(response); }
public void Saml2Binding_Get_NullOnPlainPost() { var r = new HttpRequestData("GET", new Uri("http://example.com")); Saml2PostBinding.Get(r).Should().BeNull(); }
public void AcsCommand_Run_SuccessfulResult() { var response = @"<saml2p:Response xmlns:saml2p=""urn:oasis:names:tc:SAML:2.0:protocol"" xmlns:saml2=""urn:oasis:names:tc:SAML:2.0:assertion"" ID = ""AcsCommand_Run_SuccessfulResult"" Version=""2.0"" IssueInstant=""2013-01-01T00:00:00Z""> <saml2:Issuer> https://idp.example.com </saml2:Issuer> <saml2p:Status> <saml2p:StatusCode Value=""urn:oasis:names:tc:SAML:2.0:status:Success"" /> </saml2p:Status> <saml2:Assertion Version=""2.0"" ID=""Saml2Response_GetClaims_CreateIdentity_Assertion1"" IssueInstant=""2013-09-25T00:00:00Z""> <saml2:Issuer>https://idp.example.com</saml2:Issuer> <saml2:Subject> <saml2:NameID>SomeUser</saml2:NameID> <saml2:SubjectConfirmation Method=""urn:oasis:names:tc:SAML:2.0:cm:bearer"" /> </saml2:Subject> <saml2:Conditions NotOnOrAfter=""2100-01-01T00:00:00Z"" /> </saml2:Assertion> </saml2p:Response>"; var formValue = Convert.ToBase64String(Encoding.UTF8.GetBytes( SignedXmlHelper.SignXml(response))); var r = new HttpRequestData("POST", new Uri("http://localhost"), new KeyValuePair<string, string[]>[] { new KeyValuePair<string, string[]>("SAMLResponse", new string[] { formValue }) }); var ids = new ClaimsIdentity[] { new ClaimsIdentity("Federation"), new ClaimsIdentity("ClaimsAuthenticationManager") }; ids[0].AddClaim(new Claim(ClaimTypes.NameIdentifier, "SomeUser", null, "https://idp.example.com")); ids[1].AddClaim(new Claim(ClaimTypes.Role, "RoleFromClaimsAuthManager", null, "ClaimsAuthenticationManagerMock")); var expected = new CommandResult() { Principal = new ClaimsPrincipal(ids), HttpStatusCode = HttpStatusCode.SeeOther, Location = new Uri("http://localhost/LoggedIn") }; new AcsCommand().Run(r).ShouldBeEquivalentTo(expected, opt => opt.IgnoringCyclicReferences()); }
public async Task CommandResultExtensions_Apply() { var context = TestHelpers.CreateHttpContext(); var redirectLocation = "https://destination.com/?q=http%3A%2F%2Fexample.com"; var commandResult = new CommandResult() { HttpStatusCode = System.Net.HttpStatusCode.Redirect, Location = new Uri(redirectLocation), SetCookieName = "Saml2.123", SetCookieSecureFlag = true, RelayState = "123", RequestState = GetRequestState(), ContentType = "application/json", Content = "{ value: 42 }", ClearCookieName = "Clear-Cookie", Principal = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.NameIdentifier, "SomerUser") }, "authType")), RelayData = new Dictionary <string, string>() { { "Relayed", "Value" } }, }; commandResult.Headers.Add("header", "value"); ClaimsPrincipal principal = null; AuthenticationProperties authProps = null; var authService = Substitute.For <IAuthenticationService>(); context.RequestServices.GetService(typeof(IAuthenticationService)) .Returns(authService); await authService.SignInAsync( context, "TestSignInScheme", Arg.Do <ClaimsPrincipal>(p => principal = p), Arg.Do <AuthenticationProperties>(ap => authProps = ap)); await commandResult.Apply(context, new StubDataProtector(), "TestSignInScheme", null, true); var expectedCookieData = HttpRequestData.ConvertBinaryData( StubDataProtector.Protect(commandResult.GetSerializedRequestState())); context.Response.StatusCode.Should().Be(302); context.Response.Headers["Location"].SingleOrDefault() .Should().Be(redirectLocation, "location header should be set"); context.Response.Cookies.Received().Append( "Saml2.123", expectedCookieData, Arg.Is <CookieOptions>( co => co.HttpOnly && co.Secure && co.SameSite == SameSiteMode.None)); context.Response.Cookies.Received().Delete( "Clear-Cookie", Arg.Is <CookieOptions>(co => co.Secure)); context.Response.Headers.Received().Add("header", "value"); context.Response.ContentType .Should().Be("application/json", "content type should be set"); context.Response.Body.Seek(0, SeekOrigin.Begin); new StreamReader(context.Response.Body).ReadToEnd() .Should().Be("{ value: 42 }", "content should be set"); principal.HasClaim(ClaimTypes.NameIdentifier, "SomerUser").Should().BeTrue(); authProps.Items["Relayed"].Should().Be("Value"); authProps.RedirectUri.Should().Be(redirectLocation); }
private void ReceivedChunk(IAsyncResult result) { if (disposed) return; try { int received = dataStream.EndRead(result); if (received == 0) throw new WebException("No futher data is available"); receiveResult.BytesTransferred += received; currentRequest.TotalReceived += received; // We've received everything for this piece, so null it out if (currentRequest.Complete) currentRequest = null; totalExpected -= received; receiveResult.Complete(); } catch (Exception ex) { receiveResult.Complete(ex); } finally { // If there are no more requests pending, complete the Send call if (currentRequest == null && requestMessages.Count == 0) RequestCompleted(); } }
public HttpRequest(string url, HttpRequestData data, string dest) : this(url, null, data, dest) { }