How to secure webHttpBinding? - json

In my WCF service I am trying to to send data to the client using JSON over an SSL connection. I was able to secure the OData database source to my client using wsHttpBinding with a security mode of Transport. Why is webHttpBinding not able to do the same in order to use SSL? How would I configure an endpoint that needs to use JSON to use an SSL connection as well?
Essentially what is the difference between webHttpBinding and wsHttpBinding?
<bindings>
<wsHttpBinding>
<binding name="TransportSecurity">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="EndpBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="ServiceBehavior" name="DataService4.DataService">
<endpoint address="" binding="webHttpBinding" contract="DataService4.IService" bindingConfiguration="TransportSecurity" behaviorConfiguration="EndpBehavior" />
<endpoint contract="IMetadataExchange" binding="mexHttpsBinding" address="mex" />
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />

I think this article will solve your problem.
Creating a WCF RESTful Service And Secure It Using HTTPS Over SSL

The relevant part from http://www.allenconway.net/2012/05/creating-wcf-restful-service-and-secure.html is this:
<bindings>
<webHttpBinding>
<binding>
<security mode="Transport" />
</binding>
</webHttpBinding>
</bindings>
but also remove exposing metadata if desired.
the details are documented in msdn here: https://msdn.microsoft.com/en-us/library/bb924478(v=vs.110).aspx
the relevant parts are:
Transport Security is provided using HTTPS. The service needs to be
configured with SSL certificates. The message is entirely secured
using HTTPS and the service is authenticated by the client using the
service’s SSL certificate. The client authentication is controlled
through the ClientCredentialType attribute of the transport of
webHttpBinding.

Related

Using JsonLayout with SOLR logs

I'm trying to log all events from SOLR in JSON format by using JSONLayout. I'm using the official docker image from SOLR but I can't get it to work. Here's my setup:
Dockerfile
FROM solr:7
COPY log4j2-json.xml /opt/solr/server/resources/log4j2.xml
USER root
RUN chmod 644 /opt/solr/server/resources/log4j2.xml
RUN chown solr:solr /opt/solr/server/resources/log4j2.xml
USER solr
EXPOSE 8983
CMD ["solr-precreate", "gettingstarted"]
log4j2.xml original file (without JsonLayout) which does create the solr.log file (using PatternLayout):
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<Configuration>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout>
<Pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p (%t) [%X{collection} %X{shard} %X{replica} %X{core}] %c{1.} %m%n
</Pattern>
</PatternLayout>
</Console>
<RollingFile
name="RollingFile"
fileName="${sys:solr.log.dir}/solr.log"
filePattern="${sys:solr.log.dir}/solr.log.%i" >
<PatternLayout>
<Pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p (%t) [%X{collection} %X{shard} %X{replica} %X{core}] %c{1.} %m%n
</Pattern>
</PatternLayout>
<Policies>
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="32 MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
<RollingFile
name="SlowFile"
fileName="${sys:solr.log.dir}/solr_slow_requests.log"
filePattern="${sys:solr.log.dir}/solr_slow_requests.log.%i" >
<PatternLayout>
<Pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p (%t) [%X{collection} %X{shard} %X{replica} %X{core}] %c{1.} %m%n
</Pattern>
</PatternLayout>
<Policies>
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="32 MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="org.apache.hadoop" level="warn"/>
<Logger name="org.apache.solr.update.LoggingInfoStream" level="off"/>
<Logger name="org.apache.zookeeper" level="warn"/>
<Logger name="org.apache.solr.core.SolrCore.SlowRequest" level="info" additivity="false">
<AppenderRef ref="SlowFile"/>
</Logger>
<Root level="info">
<AppenderRef ref="RollingFile"/>
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
log4j2.xml with JsonLayout in RollingFile appender which breaks it. No solr.log file is created:
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<Configuration>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout>
<Pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p (%t) [%X{collection} %X{shard} %X{replica} %X{core}] %c{1.} %m%n
</Pattern>
</PatternLayout>
</Console>
<RollingFile
name="RollingFile"
fileName="${sys:solr.log.dir}/solr.log"
filePattern="${sys:solr.log.dir}/solr.log.%i" >
<JsonLayout complete="false" compact="true" eventEol="true" />
<Policies>
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="32 MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
<RollingFile
name="SlowFile"
fileName="${sys:solr.log.dir}/solr_slow_requests.log"
filePattern="${sys:solr.log.dir}/solr_slow_requests.log.%i" >
<PatternLayout>
<Pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p (%t) [%X{collection} %X{shard} %X{replica} %X{core}] %c{1.} %m%n
</Pattern>
</PatternLayout>
<Policies>
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="32 MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="org.apache.hadoop" level="warn"/>
<Logger name="org.apache.solr.update.LoggingInfoStream" level="off"/>
<Logger name="org.apache.zookeeper" level="warn"/>
<Logger name="org.apache.solr.core.SolrCore.SlowRequest" level="info" additivity="false">
<AppenderRef ref="SlowFile"/>
</Logger>
<Root level="debug">
<AppenderRef ref="RollingFile"/>
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
I would expect to see the solr.log file to be created in the logdir and see the events in json format. But the solr.log file isn't even created. SOLR does however start.
What am I missing?
Thanks for your help.
PS. I found this thread which describes the same problem but no solution: see here
On solr official docker image 8.11.2 the same problem is caused by a missing jackson library in the classpath:
ERROR Could not create plugin of type class org.apache.logging.log4j.core.layout.JsonLayout for element JsonLayout: java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/ser/FilterProvider java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/ser/FilterProvider
at org.apache.logging.log4j.core.layout.JsonLayout.<init>(JsonLayout.java:159)
This is definitely a bug (https://issues.apache.org/jira/browse/SOLR-16342), but since the jackson library exists elsewhere in the original image, there is a possible workaround to apply while building the docker. Basically you can link the needed jackson jars that exists in /opt/solr/server/solr-webapp/webapp/WEB-INF/lib/ to /opt/solr/server/lib/ext/:
RUN ln -s /opt/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-core-2.13.3.jar /opt/solr/server/lib/ext/jackson-core-2.13.3.jar && \
ln -s /opt/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-databind-2.13.3.jar /opt/solr/server/lib/ext/jackson-databind-2.13.3.jar && \
ln -s /opt/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-annotations-2.13.3.jar /opt/solr/server/lib/ext/jackson-annotations-2.13.3.jar
Moreover:
JsonTemplate is considered deprecated. JsonTemplateLayout provides
more capabilitites and should be used instead.
(see https://logging.apache.org/log4j/2.x/manual/layouts.html#JSONLayout)
If you move to <JsonTemplateLayout /> it works out of the box in solr.

WCF Service 413 no matter which config item I change

I have been trying to figure this out for days, to no avail. This happens both when I try to debug in Visual Studio using IIS Express and with my production web site deployed to a machine running IIS 7.5.
I have called the service from a Visual Studio Unit Test using HttpWebRequest and in Fiddler 4, same errors. So I don't think this is a WCF client configuration, as I am not using one.
No matter what I change in my configuration file, I am always getting this exception:
"Exception thrown: 'System.ServiceModel.ProtocolException' in
System.ServiceModel.dll
Additional information: The maximum message size quota for incoming messages
(65536) has been exceeded. To increase the quota, use the
MaxReceivedMessageSize property on the appropriate binding element."
The below Web.config that I am attaching is for an application that is not at the root of my server.
I am calling using the json endpoint using Ajax.
I cannot for the life of me figure out why I am getting the 64K limit, especially given that I have added all of the items to the webHttpBinding as below.
I have also changed the httpRuntime element by adding the maxRequestLength item, changed the request filtering, the security settings, and a whole slew of other things that didn't make a difference.
Notice also that I have turned on tracing. The .svclog file didn't tell me anything more.
Thanks in advance for any help.
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
<add key="FactoryType" value="Production"/>
<add key="TravelRequestConnectionString" value="Data Source=ITLCS.benderson.com;Initial Catalog=TestTravelRequestSite;User Id=XXXX;Password=XXXXX"/>
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.6.1" />
<httpRuntime targetFramework="4.6.1"/>
<membership defaultProvider="ADMembershipProvider">
<providers>
<clear />
<add name="ADMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider" connectionStringName="ADConnectionString" attributeMapUsername="sAMAccountName" />
</providers>
</membership>
</system.web>
<system.serviceModel>
<services>
<service name="TravelRequestWebService.TravelRequestService">
<endpoint
address="web"
binding="basicHttpBinding"
contract="TravelRequestWebService.ITravelRequestService" />
<endpoint
address="json"
binding="webHttpBinding"
behaviorConfiguration="jsonBehavior"
contract="TravelRequestWebService.ITravelRequestService" />
<endpoint
address=""
binding="basicHttpBinding"
contract="TravelRequestWebService.ITravelRequestService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="defaultBehavior">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
<behavior name="bigBehavior">
<dataContractSerializer maxItemsInObjectGraph="200"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="WebBehavior">
<webHttp/>
</behavior>
<behavior name="jsonBehavior">
<enableWebScript/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="webHttpBinding" allowCookies="true"
maxReceivedMessageSize="20000000"
maxBufferSize="20000000">
</binding>
</webHttpBinding>
<basicHttpBinding>
<binding name="basicHttpBinding" allowCookies="true"
maxReceivedMessageSize="20000000"
maxBufferSize="20000000">
</binding>
</basicHttpBinding>
</bindings>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing"
propagateActivity="true">
<listeners>
<add name="xml" />
</listeners>
</source>
<source name="CardSpace">
<listeners>
<add name="xml" />
</listeners>
</source>
<source name="System.IO.Log">
<listeners>
<add name="xml" />
</listeners>
</source>
<source name="System.Runtime.Serialization">
<listeners>
<add name="xml" />
</listeners>
</source>
<source name="System.IdentityModel">
<listeners>
<add name="xml" />
</listeners>
</source>
</sources>
<sharedListeners>
<add name="xml"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="c:\log\Traces.svclog" />
</sharedListeners>
</system.diagnostics>
</configuration>
Try changing your config to this:
<service name="TravelRequestWebService.TravelRequestService">
<endpoint
address="web"
binding="basicHttpBinding"
bindingConfiguration="basicHttpBinding"
contract="TravelRequestWebService.ITravelRequestService" />
<endpoint
address="json"
binding="webHttpBinding"
behaviorConfiguration="jsonBehavior"
bindingConfiguration="webHttpBinding"
contract="TravelRequestWebService.ITravelRequestService" />
<endpoint
address=""
binding="basicHttpBinding"
contract="TravelRequestWebService.ITravelRequestService" />
</service>
The clue was the 64K default limit for the message size in the error message. This implied your binding configuration was not being used by WCF. The fact the configurations are named the same as the endpoint bindings added confusion.

X-Frame-Options: ALLOW-FROM a particular domain in wildfly

I have an application that's deployed on wildfly on a centos server.
I have two other applications that access a page of my application using iframe. What I access that I page, that's all I see in console:
1 Refused to display 'APP_URL' in a frame because it set 'X-Frame-Options' to 'deny'.
I know the reason behind this all and I want to allow my wildfly web-server to allow it from my 2 domains like this
X-Frame-Options: ALLOW-FROM https://example.com/
where can I configure this setting in wildfly? I know about apache server, it's done in httpd.conf file but I want to do this in wildfly.
I've configured the "SAMEORIGIN" option in wildlfy once. I suppose the "ALLOW-FROM" should be pretty similar.
You need to make this change in the undertow subsystem of Standalone.xml.
You should find the below settings in your xml.
<subsystem xmlns="urn:jboss:domain:undertow:1.0">
<buffer-caches>
<buffer-cache name="default" buffer-size="1024"
buffers-per-region="1024" max-regions="10" />
</buffer-caches>
<server name="default-server">
<http-listener name="default" socket-binding="http" />
<host name="default-host" alias="localhost">
<location name="/" handler="welcome-content" />
</host>
**<filter-ref name="xFrameOptions" />**
</server>
<servlet-container name="default"
default-buffer-cache="default" stack-trace-on-error="local-only">
<jsp-config />
<persistent-sessions />
</servlet-container>
<handlers>
<file name="welcome-content"
path="${jboss.home.dir}/welcome-content" directory-listing="true" />
</handlers>
**<filters>
<response-header name="xFrameOptions"
header-name="X-Frame-Options"
header-value="allow-from https://example.com/" />
</filters>**
</subsystem>
Make sure, you add the filter-reference and then use the reference to add the X-Frame-Options for response-header.
You can do this by manually editing the standalone.xml or by using jboss-cli.
Thanks,
Kamal

VS2012 WCF REST Service - Error: Cannot obtain metadata

I have built a WCF REST web service (WCF Service Application) and when I debug with Visual Studio 2012, it will spin up the WCF Test Client app and try to add my web service. I am getting the following error:
Error: Cannot obtain Metadata from http://localhost:50925/Service1.svc If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address. For help enabling metadata publishing, please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange Error URI: http://localhost:50925/Service1.svc Metadata contains a reference that cannot be resolved: 'http://localhost:50925/Service1.svc'. Content Type application/soap+xml; charset=utf-8 was not supported by service
I have visited the MSDN document linked above and I believe I have set up my web.config correctly.
Web.config:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="Service1" behaviorConfiguration="Service1Behavior">
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex"> </endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Service1Behavior">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
I still continue to receive the same error message. I am new to WCF / VS 2012 and .Net 4.0, but I am fluent in VS2008 .Net 2.0.
WCF REST services do not expose metadata, which is why you were getting that message (see more details in this blog post). If you're using the WCF Test Client, it's talking to a SOAP service (endpoint), not a REST one.
If you want to enable a RESTful endpoint, you can define the service element in configuration and define an endpoint inside of it which uses the webHttpBinding, and the endpoint also needs a behaviorConfiguration pointing to an endpoint behavior with the <webHttp/> behavior.
As it turns out I created a new WCF project and looked at what was going on here. VS2012/.Net 4.0 does not like the service configurations with endpoints defined. Here is my new web.config that works fine. I will need to look into why this is but at least it answers my question.
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>

Connection interrupted when using WebHttpBinding in Transport SecurityMode

I want to expose an implementation of a contract over a WebHttpBinding with SecurityMode: transport (SSL).
However, when I try to access the site via Firefox, I only get
The connection to localhost was interrupted while the page was loading.
The config file is as follows:
<configuration>
<system.serviceModel>
<services>
<service name="MyService">
<endpoint address="https://localhost"
binding="webHttpBinding"
contract="MyService"
bindingConfiguration="secureWebHttp">
</endpoint>
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="secureWebHttp">
<security mode="Transport"/>
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>
</configuration>
If host within IIS, you need to configure the hosting website security to use an ssl certificate on port 443 in this case.
You also need to configure the service behavior to set the certificate name and store. Particularly when hosting the wcf service as windows services, the certificate needs to be set for the port that you want to use. for example httpcfg.exe or netsh in vista.
Check out MSDN Configuring HTTP and HTTPS