Cannot stop Spring redirecting https to http - java

I'm developing project on a Spring Security and everything was going fine until I loaded my project to a production server. I have only http on my local machine but there is https on a production server.
And I faced an error (in case of login error):
Mixed Content: The page at 'https://my.production.com/login' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://my.production.com/api/login?error=bad-credentials'. This request has been blocked; the content must be served over HTTPS.
and (in case of success login):
Mixed Content: The page at 'https://my.production.com/login' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://my.production.com/authorities'. This request has been blocked; the content must be served over HTTPS.
I asked my vendor about this issue but they say that "There is no https between you app and nginx, so this is your app problem"...
I tried this, but this solution looks very weird and doesn't solve problem (It requires adding a lot of configuration classes and I guess it shouldn't be so hard). Actually I'm very confused how can this happen, why isn't it the default behavior to redirect to the schema that the request was made...
Also I tried adding this to my Spring Security config:
.and().requiresChannel().anyRequest().requiresSecure()
but this only causes ERR_TOO_MANY_REDIRECTS on my local machine and on a production server...
This didn't help too:
http.portMapper()
.http(8080).mapsTo(8443);
I'm not using Spring boot, but also tried this, no help.
Success authentication configuration looks like this:
SavedRequestAwareAuthenticationSuccessHandler successHandler = new
SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setDefaultTargetUrl(env.getProperty("app.authenticationSuccessUrl"));

When Apache Tomcat is running behind a HTTPS (reverse) proxy, there may be some configuration required for links and redirects to work properly.
Open conf/server.xml, find the Connector element, add the following attributes if not already present:
proxyName - set to your domain name.
proxyPort - set it to 443 if you are using the standard https port.
scheme - set to "https" if site is accessed with https.
secure - set to "true" for https.
<Connector proxyName="my.production.com" proxyPort="443" scheme="https" secure="true" ...>
Reference: Apache Tomcat 7: The HTTP Connector

Related

Put the flag secure and httponly in the cookies, in Liferay 6.2 (Localhost)

I want to apply the "secure" and "httponly" flags in the following names:
COOKIE_SUPPORT
GUEST_LANGUAGE_ID
JSESSIONID
LRF_SESSION_STATE (secure only)
ADRUM
Inside the web.xml file the following code has been added.
cookie-config image
The code shown in the image above only applies "secure" and "httponly" to JSESSIONID, but they do not affect other cookie names mentioned above.
cookies image
How could I apply the "secure" flag to the following cookie names, in Liferay 6.2?
COOKIE_SUPPORT
GUEST_LANGUAGE_ID
LRF_SESSION_STATE (secure only)
ADRUM
Regards.
I have found the solution. I was applying secure cookies on localhost, for this I had to configure the https protocol following the steps on the following web page (configure-ssl-https-support-apache-tomcat-7-server), in addition to the code fragment of the "web.xml" file exposed in my main comment.
It helped me to test on localhost.
Regards.

Security for Dropwizard admin servlet (version 1.1.1)

I'm using Dropwizard (1.1.1).
My security context is defined as such:
environment.jersey().register(new AuthDynamicFeature(new BasicCredentialAuthFilter.Builder<User>()
.setAuthenticator(new BasicAuthenticator())
.setAuthorizer(new BasicAuthorizer())
.setRealm("SECURITY REALM")
.buildAuthFilter()));
environment.jersey().register(new AuthValueFactoryProvider.Binder<>(User.class));
environment.jersey().register(RolesAllowedDynamicFeature.class);
Recently I moved my Admin page into my web application. Code is right here:
environment.getApplicationContext().setAttribute(
MetricsServlet.METRICS_REGISTRY,
environment.metrics());
environment.getApplicationContext().setAttribute(
HealthCheckServlet.HEALTH_CHECK_REGISTRY,
environment.healthChecks());
environment.getApplicationContext().addServlet(
new NonblockingServletHolder(new AdminServlet()), "/admin/*");
How can I add security context to Dropwizard admin servlet?
I have already viewed this StackOverflow answer, but nothing seems to be working. Looks like everything in that answer is deprecated.
Well, the admin servlet is a plain old servlet, not a Jersey resource. Given that you are creating a new admin servlet (are you disabling the default admin context?) in the application context, you can simply register a servlet filter to the application context like this:
environment.getApplicationContext().addFilter(new FilterHolder(new AdminServletFilter()), "/admin/*", EnumSet.of(DispatcherType.REQUEST));
Your AdminServletFilter can authenticate the user any way you like, for example if you want to do basic auth, use this implementation.
That said, if your intention is to move your admin servlet to run on the same port as your application connector, the better way to do it is via config:
server:
type: simple
adminContextPath: /admin
applicationContextPath: /
connector:
type: http
port: 8080
Also, I have updated the question you linked to with a security handler implementation that works for the latest Dropwizard version here. With this in place, you can protect the admin servlet by registering the security handler:
environment.admin().setSecurityHandler(new AdminConstraintSecurityHandler("admin", "supersecret"));

How can I produce a 503 error locally with Tomcat?

I am working on a project developed with Spring Boot using version 8.5.9 of Tomcat.
The application offers RESTfull web services in JAX RS.
In the Prod environment, sometimes I get an error 503 Service not available, but I can not reproduce it because I use my local Mock.
Is there a way to reproduce the error locally? Like putting the TomCat on hold in unavailable for a moment?
According to the MDN, HTTP 503 Service Unavailable server error means :
... response code indicates
that the server is not ready to handle the request.
The common causes are :
a server that is down for maintenance or that is overloaded.
To reproduce this error response in a natural way, you could so overloaded Tomcat.
To do it change the maximum number of simultaneous requests that can be handled by Tomcat.
If you use an embedded tomcat, set the server.tomcat.max-threads Spring Boot property with a weak value easily reachable such as :
server.tomcat.max-threads = 1
Otherwise, if you use our own Tomcat installation, set maxThreads with a weak value in the Connector element of the server.xml configuration file :
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
...
maxThreads="1"/>
You can mock it through WireMock using Java.
public static WireMockServer wireMockServer = new WireMockServer(8089);
wireMockServer.start();
final WireMock wireMock = new WireMock(8089);
wireMock.register(WireMock.get(WireMock.urlEqualTo("/conf"))
.willReturn(WireMock.aResponse()
.withStatus(503)));
Hit localhost:8089/conf to get 503 Service Unavailable

Spring MVC - How to support both http and https at the same time in Spring MVC web project

How can I support both HTTP and https at the same time in Spring MVC web project deployed on tomcat7 (and 8). I have configured every thing at Tomcat level.
HTTPS work if I use the following code by extending WebSecurityConfigurerAdapter
.and().requiresChannel().anyRequest().requiresSecure()
but then it does not allow HTTP, I need to support both HTTP AND HTTPS at the same time for same endpoint
example:
http://example.com/hello-world
https://example.com/hello-world
Changing your https configuration from .anyRequest() to a specific secure url eg. http.requiresChannel().antMatchers("/secure*").requiresSecure(); and making the rest Insecure as follows http.requiresChannel().anyRequest().requiresInsecure(); will solve the issue.
This instructs Spring to use HTTP for all requests that are not explicitly configured to use HTTPS.

Require HTTPS with Spring Security behind a reverse proxy

I have a Spring MVC application secured with Spring Security. The majority of the application uses simple HTTP to save resources, but a small part processes more confidential information and requires an HTTPS channel.
Extract from the security-config.xml :
<sec:http authentication-manager-ref="authenticationManager" ... >
...
<sec:intercept-url pattern="/sec/**" requires-channel="https"/>
<sec:intercept-url pattern="/**" requires-channel="http"/>
</sec:http>
All worked fine until we decided to migrate it to the main server, where the application servers run behind reverse proxies. And as now HTTPS is processed by the reverse proxies the application server only sees HTTP requests, and disallows access to the /sec/** hierarchy.
After some research, I found that the proxies add a X-Forwarded-Proto: https header (*), but in Spring Security HttpServletRequest.isSecure() is used to determine the channel security offered (extract from SecureChannelProcessor javadoc).
How can I tell Spring Security that a X-Forwarded-Proto: https header is enough for a secure request?
I know I could report that part on proxies configuration, but the proxies administrator really does not like that solution, because there are many application behind the proxies and the configuration could grow to a non manageable state.
I an currently using Spring Security 3.2 with XML config, but I'm ready to accept answers based on Java config and/or more recent version.
(*) Of course, the proxies remove the header if it was present in incoming request, so the application can be confident in it.
Kind of a followup to NeilMcGuigan's answer that showed that the solution was servlet container side.
Tomcat is even better. There is a valve dedicated to masking the side effects of a reverse proxy. Extract from Tomcat documentation for Remote IP Valve:
Another feature of this valve is to replace the apparent scheme (http/https), server port and request.secure with the scheme presented by a proxy or a load balancer via a request header (e.g. "X-Forwarded-Proto").
Example of the valve configuration :
<Valve className="org.apache.catalina.valves.RemoteIpValve"
internalProxies="192\.168\.0\.10|192\.168\.0\.11"
remoteIpHeader="x-forwarded-for" proxiesHeader="x-forwarded-by"
protocolHeader="x-forwarded-proto" />
That way with no other configuration of the application itself, the call to Request.isSecure() will return true if the request contains a header field of X-Forwarded-Proto=https.
I had thought of two other possibilities, but definitively prefere that one :
use a filter active before Spring Security ChannelProcessingFilter to wrap the request with a HttpServletRequestWrapper overriding isSecure() to process a X-Forwarded-Proto header - need writing and testing the filter and the wrapper
use a Spring BeanPostProcessor to look for a ChannelProcessingFilter and manually inject a ChannelDecisionManager able to consider the X-Forwarded-Proto header - really too low level
Spring Boot makes it dead simple (at least with embedded Tomcat).
1. Add the following lines to your application.properties:
server.forward-headers-strategy=native
server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=x-forwarded-proto
2. Do the following trick with your HttpSecurity configuration.
// final HttpSecurity http = ...
// Probably it will be in your `WebSecurityConfigurerAdapter.configure()`
http.requiresChannel()
.anyRequest().requiresSecure()
Source is Spring Boot reference guide
84.3 Enable HTTPS When Running behind a Proxy Server
Please also check the answer below for a specifics related to Spring Boot 2.2
If your site is HTTPS and you're running Apache Tomcat behind another system that's handling TLS termination, you can tell Tomcat to "pretend" that it's handling the TLS termination.
This makes request.isSecure() return true;
To do so, you need to add secure="true" to your Connector config in server.xml.
https://tomcat.apache.org/tomcat-7.0-doc/config/http.html
See also the scheme attribute.

Categories

Resources