I followed this article and created simplest websocket echo application. Although article is about Glassfish, I successfully run my app under Jetty 9, as they are using standard javax.websocket API in article.
It works just fine, but now I want to secure websocket connection. I googled around and found most examples are written as standalone Java application (with public static void main() method). They create new ConnectionFactory and starts server from their code (like here for example).
But I want to run my app under Jetty as a container, so I want to just specify some options in web.xml or something, to secure my connection. So I found this article and modified my web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<security-constraint>
<web-resource-collection>
<web-resource-name>Protected resource</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method>
</web-resource-collection>
<!-- https -->
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
</web-app>
The problem is it doesn't work. Probably because article is about Glassfish again.
How it is does NOT work:
My IDE (IDEA) shows red all tags inside <security-constraint>, that means schema validation is failed and these tags can not be contained inside <security-constraint>
When I try to open index.html over HTTPS I get error ssl_error_rx_record_too_long in browser and also there are two errors in Jetty output:
Illegal character 0x16 in state=START for buffer HeapByteBuffer
and
badMessage: 400 Illegal character 0x16 for HttpChannelOverHttp
So.. What I am doing wrong? How to make secured websocket via Jetty or application configuration?
The security constraint tag you described is mostly used for specify BASIC authentication mode in application server.
I guess you want to enable HTTPS and not authentication. For enabling HTTPS you may follow this article: https://wiki.eclipse.org/Jetty/Howto/Configure_SSL
I have a problem and I believe it boils down to a misfit with our load-balancer, webserver(ihs), https configuration and Java EE form security with j_security_check.
I understand that when a client tries to hit a secure page, the server (websphere) sends a redirect with the url of the signin form, which is what we see in our dev & tst environment. However the production set up has a webserver (ihs), which consumes the https url, knocks out the s and forwards the http url to websphere (known as ssl offloading). When Websphere replies with the redirect it does that without https but with http://server-name/loginform
and I see a browser error that it can't access the http://server-name/loginform.
The relevant part of web.xml:
<security-constraint>
<web-resource-collection>
<web-resource-name>Whitelist</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>authenticated-users</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>login</web-resource-name>
<url-pattern>/keepalive</url-pattern>
<url-pattern>/signin</url-pattern>
<url-pattern>/signin/error</url-pattern>
<url-pattern>/resources/*</url-pattern>
</web-resource-collection>
</security-constraint>
<security-role>
<description>Any LDAP authenticated user</description>
<role-name>authenticated-users</role-name>
</security-role>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/signin</form-login-page>
<form-error-page>/signin/error</form-error-page>
</form-login-config>
</login-config>
I'm wondering whether that's a misconfiguration on the java side (my responsibility), I expect the url in form-login-page (/login) to be relative on the browser. But I also think that the load-balancer should automatically convert a http call to https call (someone else's responsibility). I hope someone has suggestions.
You should provide a bit more information in your question such as what load balancer are you using, is it going straight to WAS or via IHS, how your web application is configured (web.xml).
So here are some general hints that might be useful for you.
Redirecting to SSL in WebSphere
If you already have security configured and login form correctly being displayed in http, you just need to add the following to web.xml:
<security-constraint>
...
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
This will ensure that WebSphere will generate redirect to https when client is trying to access protected pages.
SSL offloading
If your load balancer is configured to offload SSL and froward request to WebSphere using plain http, then you need to configure WebSphere to be aware of that. This is done by configuring httpsIndicatorHeader custom property, and adding custom header in load balancer.
When I do a http get on my websphere liberty profile v8.5.5 (let's assume http://my.domain.com) I'm presented with a nice page that says amongs other things
"Welcome to the WebSphere Application Server V8.5 Liberty Profile"
It looks like this http://rdt1.demos.ibm.com/
How do I configure my server to not display this page and perhaps redirect my request to a login page on https?
Is this a configuration related to a new context root of a new app to be installed? Like this answer below?
How to make "HTTPS redirect" work on WebSphere Application Server Liberty Profile?
I feel like this should be something configured on server.xml but I can't find any reference to this.
Thanks in advance!
You can turn that page off by adding the following to your server.xml file:
<httpDispatcher enableWelcomePage="false" />
http://www-01.ibm.com/support/knowledgecenter/api/content/nl/en-us/SSRTLW_9.0.0/com.ibm.websphere.wlp.nd.multiplatform.doc/autodita/rwlp_metatype_4ic.html#mtFile119
edit:
I should clarify, the other answer is also correct. If you install an application with "/" as the context root, it will be used instead of the main page.
If you add something like the following to that application's web.xml:
<security-constraint>
<display-name>Some constraint</display-name>
<web-resource-collection>
<web-resource-name>All</web-resource-name>
<description>All URLs</description>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<description>All users</description>
<role-name>User</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
You will get the https redirect that you're asking for.
Additional edit (per comment), the following is a more complete example of how to set up the redirect:
How to make "HTTPS redirect" work on WebSphere Application Server Liberty Profile?
Just create your application and in the server.xml specify context root as follows:
<webApplication id="MyApp" location="MyApp.war" name="MyApp" contextRoot="/"/>
If you want to redirect to login page and ssl, then you will need to do all steps in the post you quoted and of course provide login page in your application.
If you want just to disable the welcome page, add to server.xml fragment provided by ebullient or even extend it by adding some javascript code which would make the redirect:
<httpDispatcher enableWelcomePage="false" appOrContextRootMissingMessage='<script>document.location.href="/MyApp/";</script>'></httpDispatcher>
I can't seem to get Weblogic's session replication to work.
I have set-up in my web.xml such that all requests require Admin credentials:
<security-constraint>
<web-resource-collection>
<web-resource-name>redirect</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>Admin</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>myrealm</realm-name>
<form-login-config>
<form-login-page>
/login.jsp
</form-login-page>
<form-error-page>
/login.jsp
</form-error-page>
</form-login-config>
</login-config>
In my weblogic.xml, I have setup:
<session-descriptor>
<persistent-store-type>replicated_if_clustered</persistent-store-type>
</session-descriptor>
My test case is with two managed servers.
Navigate to my webpage.
Bring down one managed server. (The one that I am currently connected to)
Failover occurs and I am asked for my credentials.
I expect failover to occur seemlessly, without having me to relog in.
Try to enable session replication option in Weblogic admin console...
Logon to admin
console -> goto cluster -> goto advanced -> tick Session replication.
Note : It's not a good practise to touch .xml files to change any property....
I have a Spring web app, secured with Spring Security, running on EC2. In front of the EC2 instance is an Elastic Load Balancer with an SSL cert (https terminates at the load balancer ie. port 443 -> port 80), so from Tomcat's perspective, inbound requests are HTTP.
My login form submits to https, however the subsequent redirect goes to http (success or fail). The authentication was successful, and I can go back to https and I'm logged in.
My login configuration looks like so:
<security:form-login
default-target-url="/home"
login-page="/"
login-processing-url="/processlogin"
authentication-failure-url="/?login_error=1"/>
What do I need to change to make default-target-url and authentication-failure-url go to https?
Tomcat 6
Spring Security 3.0.x
Your spring configuration should be agnostic to the used protocol. If you use something like "requires-channel", you'll run into problems sooner or later, especially if you want to deploy the same application to a development environment without https.
Instead, consider to configure your tomcat properly. You can do this with RemoteIpValve. Depending on which headers the loadbalancer sends, your server.xml configuration needs to contain something like this:
<Valve
className="org.apache.catalina.valves.RemoteIpValve"
internalProxies=".*"
protocolHeader="X-Forwarded-Proto"
httpsServerPort="443"
/>
Spring will determine the absolute redirect address based on the ServletRequest, so change the httpsServerPort if you are using something else than 443:
The httpsServerPort is the port returned by
ServletRequest.getServerPort() when the protocolHeader indicates https
protocol
If it is a Spring Boot application (I use currently the 2.0.0 release), the following configuration within the application.properties file should be enough:
server.tomcat.protocol-header=x-forwarded-proto
This worked for me on AWS with an load balancer at the front.
For Spring Boot < 2.0.0 it should also work (not tested)
I had the same problem with Spring Boot behind Google Kubernetes. Adding these two lines to application.properties did it for me
server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=x-forwarded-proto
Source: https://docs.spring.io/spring-boot/docs/current/reference/html/howto-security.html#howto-enable-https
Solution was two fold
(1) application.yml
server:
use-forward-headers: true
(2) in servers /etc/apache2/sites-enabled/oow.com-le-ssl.conf
RequestHeader set X-Forwarded-Proto https
RequestHeader set X-Forwarded-Port 443
(2.1) and enabled the apache module with
sudo a2enmod headers
Put it together with the help of this and this
One way I got this working is by adding the following config
<http auto-config="true" use-expressions="true" entry-point-ref="authenticationEntryPoint" >
<form-login login-page="/login.jsf" authentication-failure-url="/login.jsf?login_error=t" always-use-default-target="true" default-target-url="xxxxx" />
<logout logout-url="/logout" logout-success-url="/logoutSuccess.jsf" />
...
</http>
Had to add always-use-default-target="true" and default-target-url="https://....". Not the ideal way as you need to hard code the url in the config.
I set requires-channel="any" on all intercept-urls. This allows it to still work in my dev environment where I don't use SSL.
<intercept-url pattern="/createUser" access="permitAll" requires-channel="any"/>
<intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" requires-channel="any"/>
<intercept-url pattern="/**" access="isAuthenticated()" requires-channel="any"/>
Then, create an apache virtual host that redirects all traffic to the HTTPS version.
<VirtualHost *:80>
ServerName www.mywebsite.com
Redirect permanent / https://www.mywebsite.com/
</VirtualHost>
I am also facing exactly same problem and till the time I get proper solution I am redirecting my requests from proxy server to tomcat server over AJP instead of HTTP.
Below is my apache configuration
ProxyPass /myproject ajp://localhost:8009/myproject
ProxyPassReverse /myproject ajp://localhost:8009/myproject
use below lines of code in web.xml
<security-constraint>
<web-resource-collection>
<web-resource-name>Login and Restricted Space URLs</web-resource-name>
<url-pattern>/j_security_check</url-pattern>
<url-pattern>/loginpage.rose</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
it makes forced to use HTTPS.
In my case, I had to REMOVE the property server.use-forward-headers=true.
This is my setup:
Digital Ocean LB --> Kubernetes cluster with Ingress --> Spring boot Application
Tried everything mentioned above for my k8's to spring boot application, problem was k8 was secured and ssl was handled by SSL accelerator sitting in front of ingress. The application only received http requests and spring security also forwarded to http, which was never found. The solution that worked for me:
nginx.ingress.kubernetes.io/proxy-redirect-from: http://$http_host/
nginx.ingress.kubernetes.io/proxy-redirect-to: https://$http_host/$namespace/helloworld-service/