Embracing the Messiness in Search of Epic Solutions

Spring Security: Forcing URLs to use HTTPS

Posted

in

PROBLEM

Your web application supports both HTTP and HTTPS. You want to force all URLs to use HTTPS.

SOLUTION

Spring Security has a simple configuration that allows us to redirect all HTTP-based URLs to HTTPS. All we have to do is to set requires-channel=”https” on <security:intercept-url/> tag.

For example:-

<security:http auto-config="true">
	<security:form-login .../>
	<security:logout .../>

	<security:intercept-url pattern="/reports" access="ROLE_ADMIN" requires-channel="https"/>
	<security:intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" requires-channel="https"/>
	<security:intercept-url pattern="/**" access="ROLE_USER" requires-channel="https"/>
</security:http>

With this configuration, when the user hits http://server/app, it will be redirected to https://server/app.

If we are seeing this “redirect loop” error…

… and the server log went bananas…

"GET /app HTTP/1.1" 302 0
"GET /app/ HTTP/1.1" 302 0
"GET /app/app/ HTTP/1.1" 302 0
"GET /app/app/app/ HTTP/1.1" 302 0
"GET /app/app/app/app/ HTTP/1.1" 302 0
"GET /app/app/app/app/app/ HTTP/1.1" 302 0
"GET /app/app/app/app/app/app/ HTTP/1.1" 302 0
"GET /app/app/app/app/app/app/app/ HTTP/1.1" 302 0
"GET /app/app/app/app/app/app/app/app/ HTTP/1.1" 302 0
"GET /app/app/app/app/app/app/app/app/app/ HTTP/1.1" 302 0

… then, chances are we are not using the default HTTP port (80) and HTTPS port (443). To fix this, we have to specify the custom port mappings in the Spring Security configuration:-

<security:http auto-config="true">
	<security:form-login .../>
	<security:logout .../>

	<security:intercept-url pattern="/reports" access="ROLE_ADMIN" requires-channel="https"/>
	<security:intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" requires-channel="https"/>
	<security:intercept-url pattern="/**" access="ROLE_USER" requires-channel="https"/>

	<security:port-mappings>
		<!-- Default ports -->
		<security:port-mapping http="80" https="443"/>
		<!-- Websphere default ports -->
		<security:port-mapping http="9080" https="9443"/>
		<!-- Tomcat default ports -->
		<security:port-mapping http="8080" https="8443"/>
		<!-- Jetty custom ports -->
		<security:port-mapping http="7777" https="7443"/>
	</security:port-mappings>
</security:http>

Now, when the user hits http://localhost:7777/app, it will be redirected to https://localhost:7443/app.

Comments

One response to “Spring Security: Forcing URLs to use HTTPS”

Leave a Reply