Configuring Liberty with httpProxyRedirect - websphere

I am attempting to redirect traffic on insecure port to secure port as described here:
https://www.ibm.com/support/knowledgecenter/en/SSD28V_9.0.0/com.ibm.websphere.liberty.autogen.core.doc/ae/rwlp_config_httpProxyRedirect.html
Instead both ports are available and I see nothing in the logs. It's as if the httpProxyRedirect isn't being configured at all.
<?xml version="1.0" encoding="UTF-8"?>
<server description="CAST Liberty Server">
<!-- Enable features -->
<featureManager>
<feature>webProfile-7.0</feature>
</featureManager>
<application id="app" context-root="/" type="war" location="${war.name}">
<classloader apiTypeVisibility="spec, ibm-api, api, third-party" />
</application>
<httpProxyRedirect id="defaultHttpProxyRedirect" httpPort="${http.port}" httpsPort="${https.port}" />
<keyStore id="defaultKeyStore" password="pass" />
<httpEndpoint host="*" httpPort="${http.port}" httpsPort="${https.port}" id="defaultHttpEndpoint" />
<applicationMonitor updateTrigger="mbean" />
</server>

Most likely, you are missing the security-constraints in the web.xml. This configuration tells the server which URLs need to be accessed over a secure transport and then re-directs qualifying requests from the non-secure port to the secure port. This tutorial may help: https://docs.oracle.com/cd/E19798-01/821-1841/bncbk/index.html
Also, keep in mind that the httpProxyRedirect configuration in the server.xml is intended for redirecting when you have a proxy server in front of your application server. For example, you may have your proxy server on the main "www.ibm.com" host - listening on HTTP port 80 and HTTPS port 443. But that host may route some requests to your Liberty application server on some other host (like "app1host.internal.ibm.com") that listens on different ports (i.e. HTTP port 9080 and HTTPS port 9443). In that case, just using the security-constraints in the web.xml would attempt to redirect the client request on the Liberty server from 9080 to 9443 but on the www.ibm.com host - where nothing is listening on those ports. In this case, you should configure httpProxyRedirect like this:
<httpProxyRedirect httpPort="80" httpsPort="443" host="www.ibm.com" />
With the configuration, a client HTTP request to a secured URL will get redirected to www.ibm.com on port 443, where the proxy server will forward the request to app1host.internal.ibm.com port 9443.
Hope this helps,
Andy

This is the security constraint that i am using in my web.xml and it works well for both Tomcat and IBM Websphere 8.5.5.15:
<security-constraint>
<web-resource-collection>
<web-resource-name>Entire Application</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
Note: make sure that you put it after your <servlet-mapping>.

Related

How to secure a camel cxf endpoint (https) in FUSE 7.6?

We have been using camel-cxf service endpoints for multiple applications. They works well. Recently we have a need to secure these service endpoints. Therefore, we are adding <httpu:engine-factory> configuration to the camel-context.xml.
We also configured FUSE 7.6 server to have the secure port at 8183 by setting
[FUSE 7.6 Install]/etc/org.ops4j.pax.web.cfg file:
org.osgi.service.http.port = 8181
org.osgi.service.http.port.secure = 8183
org.ops4j.pax.web.config.file = ${karaf.etc}/undertow.xml
org.ops4j.pax.web.session.cookie.httpOnly = false
org.ops4j.pax.web.session.cookie.secure = true
[FUSE 7.6 Install]/etc/undertow.xml is correctly configured to point
to right keystore and truststore, etc.
Following is the camel-context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:cxf="http://camel.apache.org/schema/blueprint/cxf"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sec="http://cxf.apache.org/configuration/security"
xmlns:http="http://cxf.apache.org/transports/http/configuration"
xmlns:httpu="http://cxf.apache.org/transports/http-undertow/configuration"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0
https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://cxf.apache.org/configuration/security
http://cxf.apache.org/schemas/configuration/security.xsd
http://cxf.apache.org/transports/http/configuration
http://cxf.apache.org/schemas/configuration/http-conf.xsd
http://cxf.apache.org/transports/http-undertow/configuration
http://cxf.apache.org/schemas/configuration/http-undertow.xsd">
<bean class="com.mycom.myapp.CamelRequestProcessor" id="myProcessor"/>
<cxf:cxfEndpoint address="{{MY_HOST}}:8185{{MY_SVC_ADDRESS}}"
bus="auditBus" id="myWebServiceEndpoint"
serviceClass="com.mycom.myapp.MyWebServiceEndpoint" wsdlURL="wsdl/mySvc.wsdl"/>
<httpu:engine-factory bus="cxf">
<httpu:engine port="8185">
<httpu:tlsServerParameters secureSocketProtocol="$(MY_SECURE_SOCKET_PROTOCOL)">
<sec:keyManagers keyPassword="$(MY_KEY_PASSWORD)">
<sec:keyStore file="$(MY_KEYSTORE)" password="$(MY_KEYSTORE_PASSWORD)" type="JKS"/>
</sec:keyManagers>
<sec:trustManagers>
<sec:keyStore file="$(MY_TRUSTSTORE)" password="$(MY_TRUSTSTORE_PASSWORD)" type="JKS"/>
</sec:trustManagers>
<sec:clientAuthentication required="true" want="true"/>
</httpu:tlsServerParameters>
</httpu:engine>
</httpu:engine-factory>
<camelContext id="_myCamelContext" useBlueprintPropertyResolver="true" errorHandlerRef="myErrorHandler">
<route id="_firstRuote">
<from id="_from" uri="cxf:bean:myWebServiceEndpoint"/>
<bean id="_processor" method="process" ref="myProcessor"/>
<to id="_to4" uri="direct:otherEndpoints"/>
</route>
</camelContext>
</blueprint>
After we add <httpu:engine-factory/>section, the code is built and deployed to FUSE 7.6. Everything goes well. There is no error in the log, and the bundle starts normally. When I inspected the service at https://myhost:8183/cxf, the service is displayed in browser
Endpoint address: https://my host:8185/cxf/MyWebServiceEndpoint/<br>
WSDL : {namespace}MyWebServiceEndpoint <--This is a link-->
However, when I click the WSDL link, it spins a few seconds, then displays "Unable to connect". It should display the WSDL file.
The browser address bar does point to the correct URL
https://myhost:8185/cxf/MyWebServiceEndpoint/?wsdl
Any help is greatly appreciated.
Your camel-cxf endpoint has
<sec:clientAuthentication required="true" want="true"/>
Which means your client(in this case a browser to load the wsdl) also needs to provide the private key(keystore).
Did you import truststore/keystore that you used for the camel-cxf endpoint into your browser?
The issue is resolved. The undertow configuration has to specify host as the following, which makes the port accessible:
<httpu:engine host="0.0.0.0" port="8185">

Liberty server 19.0.0.9 -how to authorize unauthenticated user

I have new problem with container security . On the server i have two ears first call service from second. On service there is #RolesAllowed("Authenticated"). My configuration in server.xml looks like this:
<featureManager>
<feature>jndi-1.0</feature>
<feature>distributedMap-1.0</feature>
<feature>localConnector-1.0</feature>
<feature>wasJmsClient-2.0</feature>
<feature>jdbc-4.1</feature-->
<feature>javaMail-1.5</feature>
<feature>json-1.0</feature>
<feature>adminCenter-1.0</feature>
<feature>appSecurity-2.0</feature>
<feature>beanValidation-2.0</feature>
<feature>cdi-2.0</feature>
<feature>jsf-2.3</feature>
<feature>mdb-3.2</feature>
<feature>ejbHome-3.2</feature>
<feature>ejbLite-3.2</feature>
<feature>ejbRemote-3.2</feature>
<feature>jca-1.7</feature>
<feature>concurrent-1.0</feature>
<feature>jms-2.0</feature>
<feature>appClientSupport-1.0</feature>
<feature>ldapRegistry-3.0</feature>
</featureManager>
<basicRegistry id="basic" realm="customRealm">
<user password="{xor}Ozo5Kiw6LQ==" name="defuser" />
</basicRegistry>
Both ears contains identical configuration
<application-bnd>
<security-role name="All Role">
<special-subject type="ALL_AUTHENTICATED_USERS" />
</security-role>
</application-bnd>
The second ear contains ibm-application-ibd.xml file but i can not edit it. Best would be to override it.
When i call service from second ear i still get exception :
Caused by: javax.ejb.EJBAccessException: CWWKS9400A: Authorization failed for user UNAUTHENTICATED while invoking
Eny ideas ?
Liberty allows you to override application binding files using the server config element application-bnd, see IBM KnowledgeCenter topic https://www.ibm.com/support/knowledgecenter/en/SSEQTP_liberty/com.ibm.websphere.liberty.autogen.base.doc/ae/rwlp_config_enterpriseApplication.html#application-bnd and https://www.ibm.com/support/knowledgecenter/en/SSEQTP_liberty/com.ibm.websphere.wlp.doc/ae/twlp_sec_rolebased.html for details.
According to my experience configuring the authentication with Websphere Liberty, the login showed up only for restricted pages only, so the app needs to definen some security constraint in the web.xml like this example:
<security-constraint>
<web-resource-collection>
<web-resource-name>Secured API</web-resource-name>
<url-pattern>/s/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>user</role-name>
</auth-constraint>
</security-constraint>
<security-role>
<role-name>user</role-name>
</security-role>

IBM Liberty client certificate authentication

I am trying to configure my liberty server for client certificate authentication by these steps:
http://www.ibm.com/support/knowledgecenter/SS7K4U_liberty/com.ibm.websphere.wlp.zseries.doc/ae/twlp_sec_clientcert.html
My liberty configuration:
<server description="new server">
<!-- Enable features -->
<featureManager>
<feature>webProfile-7.0</feature>
<feature>restConnector-1.0</feature>
<feature>localConnector-1.0</feature>
<feature>monitor-1.0</feature>
<feature>jsp-2.3</feature>
<feature>adminCenter-1.0</feature>
<feature>ssl-1.0</feature>
</featureManager>
<!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
<httpEndpoint id="defaultHttpEndpoint"
httpPort="9081"
httpsPort="9444" />
<application id="Sample" name="Sample" type="war" location="Sample.war"/>
<keyStore id="defaultKeyStore" location="key.jks" type="JKS" password="{xor}EzY9Oi0rJg==" />
<keyStore id="defaultTrustStore" location="truststore.jks" type="JKS" password="{xor}EzY9Oi0rJg==" />
<ssl id="defaultSSLConfig" keyStoreRef="defaultKeyStore" trustStoreRef="defaultTrustStore" clientAuthenticationSupported="true"/>
<webAppSecurity allowFailOverToBasicAuth="true" />
<auth-method>CLIENT-CERT</auth-method>
<basicRegistry id="basic">
<user identity="CN=Admin,O=myOrg,C=country" name="Admin" password="admin" />-->
</basicRegistry>
<administrator-role>
<user>Admin</user>
</administrator-role>
</server>
From java client I get:
CWWKX0229E: There was a problem with the user credentials provided. The server responded with code 401 and message 'Unauthorized'
I think my user mapping is wrong. Can somebody give me an example how to map client certificate with the liberty user?
Is the intent to login to web application using the certificate rather than user/password? You need to define the CLIENT-CERT in web.xml. You will have to install the certificate on your browser from where application will be accesses. Also, Liberty server will need to have the signer certificate in the trust store. You may also define certificate filter if the certificate DN name does match exactly to registry user.
Below command can be added to server.xml so that basic authentication can be use if client certificate authentication did not succeed.
You may also want to confirm that your application does work with basic authentication.
More details at:
http://www.ibm.com/support/knowledgecenter/SSEQTP_8.5.5/com.ibm.websphere.wlp.doc/ae/twlp_sec_clientcert.html

Forcing HTTPS redirect on Wildfly 10.0 directs to https://localhost:8443

I am having a very challenging time forcing HTTPS on a Bitnami Ubutnu Wildfly 10 install.
The HTTPS works fine (e.g. https://example.com works great)
I have tried many different things with no result. Here are some highlights of what I've done:
I modified my web.xml to add this (note MYWEBNAME was replaced with my war file name):
<security-constraint>
<web-resource-collection>
<web-resource-name>MYWEBNAME</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
I modified /opt/bitnami/apache2/conf/bitnami/bitnami.conf (as per https://docs.bitnami.com/aws/components/apache/):
<VirtualHost _default_:80>
DocumentRoot /opt/bitnami/apache2/htdocs"
ADD: RewriteEngine On
ADD: RewriteCond %{HTTPS} !=on
ADD: RewriteRule ^/(.*) https://%{SERVER_NAME}/$1 [R,L]
...
</VirtualHost>
I modified standalone.xml
<management-interfaces>
<http-interface security-realm="ApplicationRealm" http-upgrade-enabled="true">
<socket-binding https="management-https"/>
</http-interface>
</management-interfaces>
I modified my root index.html to redirect to:
<SCRIPT>document.location="https://example.com";</SCRIPT>
As per Wildfly 9 http to https, I tried this:
<http-interface security-realm="ManagementRealm" http-upgrade-enabled="true">
<socket interface="management" secure-port="${jboss.management.http.port:9990}"/>
</http-interface>
this resulted in a 503 error and wildfly to die, so I removed it.
What I have now, is http://example.com redirecting to https://localhost:8443
So I think it's close, I just cannot figure out how to make it redirect to https://example.com:8443 instead
I m not using Apache proxing Wildfly. But in my setup, all request on port 80 or 8080 (http://example.com or http://example.com:8080) is redirected to port 443 (https://example.com).
It is done making iptables to redirect traffic from 80 to 8080 and 443 to 8443 and than wildfly redirects CONFIDENTIAL transport requests to port 443 instead 8443.
Please see if it is helpful: make wildfly listen on port 443 not 8443
By the way, use javascript or any other client side script to redirect to SSL is not safe enough once the responsability of the redirection is in the client side.
For others looking for a solution, here's a summary of what I did - all in one spot. This is a summary of the links located in this thread, so h/t to those authors who answered the question. The credit belongs to them, this is just a summary of what worked for me.
1. Add an IPTABLES routing rule to route port 443 to 8443.
sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443
Hint: to see what rules you already have in place, use:
sudo iptables -t nat -L -n -v
2. Add a Rewrite Filter and a Predicate to the configuration. Add the entries shown on line 10 and 24 of the snippet.
<subsystem xmlns="urn:jboss:domain:undertow:3.0">
<buffer-cache name="default"/>
<server name="default-server">
<http-listener name="default" socket-binding="http" redirect-socket="https"/>
<https-listener name="default-ssl" security-realm="ApplicationRealm" socket-binding="https"/>
<host name="default-host" default-web-module="YOURWARFILENAMEHERE.war" alias="localhost">
<location name="/" handler="welcome-content"/>
<filter-ref name="server-header"/>
<filter-ref name="x-powered-by-header"/>
<filter-ref name="http-to-https" predicate="equals(%p,8080)"/>
<!-- ADD THE filter-ref ENTRY ABOVE -->
</host>
</server>
<servlet-container name="default">
<jsp-config/>
<websockets/>
</servlet-container>
<handlers>
<file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
</handlers>
<filters>
<response-header name="server-header" header-name="Server" header-value="WildFly/10"/>
<response-header name="x-powered-by-header" header-name="X-Powered-By" header-value="Undertow/1"/>
<rewrite name="http-to-https" redirect="true" target="https://DOMAINNAMEHERE:8443%U"/>
<!-- ADD THE rewrite ENTRY ABOVE, BE SURE TO SUBSTITUTE YOUR DOMAIN NAME -->
</filters>
</subsystem>
Note: I wondered if adding an iptables reroute from 8080 to 8443 using the command in step 1 would be sufficient and eliminate the need for step 2. But step 2 worked for me so I went with it. I'll leave trying that option up to the reader if they want.
3. Modify The Management Interfaces section of the standalone.xml.
<management-interfaces>
<http-interface security-realm="ManagementRealm" http-upgrade-enabled="true">
<socket-binding https="management-https"/>
</http-interface>
</management-interfaces>
Note that this replaced the binding to http. Also note this step may not be directly related to the forwarding of HTTP to HTTPS but rather just a step in the HTTPS setup.
4. Restart your Wildfly instance.

IBM Websphere Liberty Profile:How to map Public IP Address in Websphere

I am trying to map my server public ip addresss in Websphere LP server.xml file but when i tried to access it from outside i am getting a connection error. I tried giving host="localhost" and tried to access from server itself,it is working fine.
Is there anything i need to configure in Websphere LP to access it from outside.
Server.xml file
<server description="new server">
<!-- Enable features -->
<featureManager>
<feature>jsp-2.2</feature>
<feature>localConnector-1.0</feature>
</featureManager>
<httpEndpoint host="*" httpPort="8007" httpsPort="9443" id="defaultHttpEndpoint"/>
<applicationMonitor updateTrigger="mbean"/>
<library id="worklight-6.0.0">
<fileset dir="C:\IBM\Liberty\usr\shared\resources" includes="worklight-jee-library-6.0.0.jar"/>
</library>
<library id="apps-common">
<fileset dir="C:\IBM\Liberty\usr\shared\resources" includes="org.hsqldb.hsqldb_2.2.5.jar"/>
</library>
<application context-root="/DemoApp" id="DemoApplication" location="DemoApplication.war" name="DemoApplication" type="war">
<classloader commonLibraryRef="worklight-6.0.0,apps-common"/>
</application>
</server>
Any help is appreciated.
As per the InfoCenter document for the httpEndpoint configuration element, here: http://pic.dhe.ibm.com/infocenter/wasinfo/v8r5/topic/com.ibm.websphere.wlp.doc/autodita/rwlp_metatype_4ic.html?resultof=%22%68%74%74%70%65%6e%64%70%6f%69%6e%74%22%20#mtFile121
A hostname of * will bind to all available network interfaces - you do not need to do anything extra on the Liberty side, which I believe answers your question.
Setting the hostname to 'localhost' will mean the http endpoint is only accessible from your machine.
Using the configuration as supplied (hostName of *), this should work remotely - so it is likely a firewall issue.
You can check the /servers/yourServer/logs/messages.log file to verify which interfaces your endpoint is binding to - look for a message of the form
WWKO0219I: TCP Channel defaultHttpEndpoint has been started and is now listening for requests on host localhost (IPv4: 127.0.0.1) port 9080.

Resources