Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Spring how to force https ssl in webapplicationinitializer?

To force https in web.xml i was using this code snippet:

<security-constraint>
  <web-resource-collection>
      <url-pattern>/*</url-pattern>
  </web-resource-collection>
  <user-data-constraint>
      <transport-guarantee>CONFIDENTIAL</transport-guarantee>
  </user-data-constraint>
</security-constraint>

Is there an equivalent for this in Spring Java Config? I already figured out that i need a ServletSecurityElement. But how do i connect it to the rest?

public class WebAppInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext container) throws ServletException {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        container.addListener(new ContextLoaderListener(context));
        context.register(PersistenceJPAConfig.class);

        FilterRegistration filter = container.addFilter("wicket.myproject", WicketFilter.class);
        filter.setInitParameter("applicationClassName", WicketApplication.class.getName());
        filter.setInitParameter(WicketFilter.FILTER_MAPPING_PARAM, "/*");
        filter.addMappingForUrlPatterns(null, false, "/*");

        HttpConstraintElement forceHttpsConstraint = new HttpConstraintElement(ServletSecurity.TransportGuarantee.CONFIDENTIAL, "");
        ServletSecurityElement securityElement = new ServletSecurityElement(forceHttpsConstraint);
    }
}
like image 325
Robert Niestroj Avatar asked Feb 13 '15 21:02

Robert Niestroj


4 Answers

As John Thompson pointed out you were right there. You just needed to add the security element you defined to the servlet. On another note I noticed you had "" as the roleNames parameter to the HttpConstraintElement. This would actually cause everyone who didn't have the role "" to be denied. If you want this to work like normal (force https) don't give any roles. In the end this worked for me:

public class ApplicationInitializer implements WebApplicationInitializer {

    private static final String DISPATCHER_SERVLET_NAME = "dispatcher";
    private static final String DISPATCHER_SERVLET_MAPPING = "/";

    @Override
    public void onStartup(ServletContext container) throws ServletException {
        // Create the dispatcher servlet's Spring application context
        AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
        dispatcherContext.register(ApplicationConfiguration.class);

        // Register and map the dispatcher servlet
        ServletRegistration.Dynamic dispatcher = container.addServlet(DISPATCHER_SERVLET_NAME, new DispatcherServlet(dispatcherContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping(DISPATCHER_SERVLET_MAPPING);

        // Force HTTPS, and don't specify any roles for this constraint
        HttpConstraintElement forceHttpsConstraint = new HttpConstraintElement(ServletSecurity.TransportGuarantee.CONFIDENTIAL);
        ServletSecurityElement securityElement = new ServletSecurityElement(forceHttpsConstraint);

        // Add the security element to the servlet
        dispatcher.setServletSecurity(securityElement);
    }
}
like image 175
Adam Avatar answered Nov 16 '22 08:11

Adam


I think you need to get a handle on the servlet registration, then register the security element. Try something like this:

ServletRegistration.Dynamic registration 
     = container.addServlet("dispatcher", new DispatcherServlet());
registration.setLoadOnStartup(1);
registration.setServletSecurity(securityElement); //your prev defined securityElement
like image 35
John Thompson Avatar answered Nov 16 '22 08:11

John Thompson


In the case if you use Spring Security 3.2 you could do this as follows.

<security:intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" requires-channel="https"/>

with http to https port mappings as well.

<security:port-mappings>
            <security:port-mapping http="${port.mapping.http.port}"
                https="${port.mapping.https.port}" />
like image 1
Robert Avatar answered Nov 16 '22 08:11

Robert


private static final String DISPATCHER_SERVLET_NAME = "dispatcher";
private static final String DISPATCHER_SERVLET_MAPPING = "/";    
@Override
        public void onStartup(ServletContext servletContext) throws ServletException {
            AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
            rootContext.register(ApplicationContext.class);

            ServletRegistration.Dynamic dispatcher = servletContext.addServlet(DISPATCHER_SERVLET_NAME,
                    new DispatcherServlet(rootContext));
            dispatcher.setLoadOnStartup(1);
            dispatcher.addMapping(DISPATCHER_SERVLET_MAPPING);



             HttpConstraintElement forceHttpsConstraint = new HttpConstraintElement(TransportGuarantee.CONFIDENTIAL);
                ServletSecurityElement securityElement = new ServletSecurityElement(forceHttpsConstraint);
               dispatcher.setServletSecurity(securityElement);


        }
like image 1
Kamlesh Delat Avatar answered Nov 16 '22 06:11

Kamlesh Delat