Close

Spring Security - HTTP/HTTPS Channel Security

[Updated: Jan 24, 2018, Created: Jan 23, 2018]

Spring Security supports both HTTP and HTTPS. In our application, we can specify particular URL pattern which can only be accessed over HTTPS. That means even if a user attempts to access those URLs using HTTP, it will be redirected to the HTTPS.

Example

Java Config class

@Configuration
@EnableWebSecurity
@EnableWebMvc
@ComponentScan
public class AppConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
      http.authorizeRequests()
          .antMatchers("/users/**").hasRole("USER")
          .antMatchers("/quests/**").permitAll()
          .anyRequest().authenticated()
          .and()
          .formLogin()
          .and()
          //following enables https for the specified URL pattern
          .requiresChannel().antMatchers("/users/**").requiresSecure();
  }

  @Override
  public void configure(AuthenticationManagerBuilder builder)
          throws Exception {
      builder.inMemoryAuthentication()
             .withUser("joe")
             .password(passwordEncoder().encode("123"))
             .roles("USER");
  }

  @Bean
  public PasswordEncoder passwordEncoder() {
      return new BCryptPasswordEncoder();
  }

  @Bean
  public ViewResolver viewResolver() {
      InternalResourceViewResolver vr = new InternalResourceViewResolver();
      vr.setPrefix("/WEB-INF/views/");
      vr.setSuffix(".jsp");
      return vr;
  }
}

Controller

@Controller
public class MyController {

  @RequestMapping(value = {"/users/**","/quests/**"})
  public String handleRequest(HttpServletRequest request, Model model) {
      Authentication auth = SecurityContextHolder.getContext()
                                                 .getAuthentication();
      model.addAttribute("uri", request.getRequestURI())
           .addAttribute("user", auth.getName())
           .addAttribute("roles", auth.getAuthorities());
      return "my-page";
  }
}

View

src/main/webapp/WEB-INF/views/my-page.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html lang="en">
<body>
 <p>URI: ${uri} <br/>
 User :  ${user} <br/>
 roles:  ${roles} <br/><br/>
 <a href="http://localhost:8080/users/">/users/</a><br/>
 <a href="http://localhost:8080/quests/">/quests/</a><br/><br/>
 </p>
 <form action="/logout" method="post">
     <input type="hidden"
            name="${_csrf.parameterName}"
            value="${_csrf.token}"/>
  <input type="submit" value="Logout">
</form>
</body>
</html>

As seen above, both links' href attributes are specified with 'http'. Clicking on /users/, however, will be redirected to 'https' per our Java config.

Configuring tomcat7-maven-plugin to use HTTPS

For testing purpose or even in dev environment, we can configure tomcat7-maven-plugin to access HTTPS URLs:

 <plugin>
     <groupId>org.apache.tomcat.maven</groupId>
     <artifactId>tomcat7-maven-plugin</artifactId>
     <version>2.2</version>
     <configuration>
         <path>/</path>
         <httpsPort>8443</httpsPort>
         <keystoreFile>C:\my-cert-dir\localhost-rsa.jks</keystoreFile>
         <keystorePass>123456</keystorePass>
     </configuration>
 </plugin>

The keystore file should be created by keytool at the location specified above by <keystoreFile/>. Checkout this tutorial for details.

Running the example application

To try examples, run embedded tomcat (configured in pom.xml of example project below):

mvn tomcat7:run-war

Output

Entering 'localhost:8080/quests/' in the address bar:

Clicking on '/users/' will be redirected to 'https' and as we have configured this URL to be accessed only by 'USER' role, login form will be shown at first access:

Note that Chrome shows 'Not secure' warning for self-signed certificate. For a real production application, we should get the certificate from a certificate authority.

Entering valid user/password and clicking on 'Login' button:

Clicking on /quests/:

'/quests/' can also be accessed via https. Entering 'https://localhost:8443/quests/' in the address bar:

Example Project

Dependencies and Technologies Used:

  • spring-security-web 5.0.0.RELEASE: spring-security-web.
  • spring-security-config 5.0.0.RELEASE: spring-security-config.
  • spring-webmvc 5.0.0.RELEASE: Spring Web MVC.
  • javax.servlet-api 3.1.0 Java Servlet API
  • jstl 1.2 javax.servlet:jstl
  • JDK 1.8
  • Maven 3.3.9

HTTP/HTTPS Channel Security Example Select All Download
  • spring-https-channel-security
    • src
      • main
        • java
          • com
            • logicbig
              • example
        • webapp
          • WEB-INF
            • views

See Also