SockJS secure connection with IE8+

362 views
Skip to first unread message

ljmc...@gmail.com

unread,
Feb 24, 2014, 12:12:21 PM2/24/14
to soc...@googlegroups.com
Afternoon everyone. I'm having an issue with sockjs and Spring4. I don't know which side of the setup is causing the issue. The problem is I can't seem to get IE8 to open a connection to my Spring backend over HTTPS.

I'm trying to implament this example: https://demo.rasc.ch/spring4ws/
The link I'm trying is the chat.
The link to his source is here: https://github.com/ralscha/spring4ws-demos

The only change I made to his source is I'm using jquery-1.9.1 , Spring 4.0.0, and the full stomp.js and not the stomp.min.js

The sock and stomp code in the index page for the chat client is:
        $(function() {
          var username, lastUsername, stompClient, content = $("#content")[0],
          input = $("#editor input")[0];

          function notify(text) {
              $('<p class="message notice"/>').text(text).appendTo(content);
                  content.scrollTop = content.scrollHeight;
          }

          $(input).keyup(function(event) {
              if (event.which === 13 && $.trim(input.value)) {
                  if (!username) {
                     username = input.value;
                     $("#editor p").addClass("user").removeClass("guide").text(username);

                    var path = window.location.pathname.substring(0,
                    window.location.pathname.lastIndexOf('/')+1);

                    var sock = new SockJS(path + 'chat');
                    stompClient = Stomp.over(sock);

                    stompClient.connect({}, function(frame) {
                         notify("The connection has been opened");
                         $(input).removeAttr("disabled").focus();

                         stompClient.subscribe("/queue/chatmessage", function(msg) {
                               var data = JSON.parse(msg.body);

                               if (lastUsername !== data.username) {
                                  lastUsername = data.username;

                                  $('<p class="user"/>').text(data.username).appendTo(content);
                    }

                     $('<p class="message"/>').text(data.message).appendTo(content);
                     content.scrollTop = content.scrollHeight;

                });
            },
    function(error) {
         notify("An error occured: " + error);
         $(input).attr("disabled", "disabled");
      });
    } else {
      stompClient.send("/queue/chatmessage", {}, JSON.stringify({username: username, message: input.value}));
    }
     input.value = "";
    }
    });
    $(input).focus();
    $(window).resize(function() {
    $(content).height($(window).height() - $("#editor").outerHeight(true) - 15).scrollTop(content.scrollHeight);
    }).resize();
    });

Sorry about the formatting.

In Spring all I did was separate the the webconfig java file into 2 files

WebConfig is standard. Extends WebMvcConfigurerAdapter :

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
      registry.addViewController("/").setViewName("index.html");
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
     configurer.enable();
   }

WebSocket implaments WebSocketMessageBrokerConfigurer:

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
      registry.addEndpoint("/chat").withSockJS().setSessionCookieNeeded(false);
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
      registry.enableSimpleBroker("/queue/");
    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
      // use default thread pool with 1 thread
    }

    @Override
    public void configureClientOutboundChannel(ChannelRegistration registration) {
      registration.taskExecutor().corePoolSize(2).maxPoolSize(3);
    }

The initilizer is basic too.

    @Override
    protected Class<?>[] getServletConfigClasses() {
      return new Class<?>[] { WebConfig.class, WebSocketConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
      return new String[] { "/chatdemo/*" };
    }

I'm also running this through Tomcat 7 using eclipse. So not the embedded tomcat.

The problem I'm having is the readystate inside sock is being set to permanent in IE. I don't fully understand xhr/xdr polling, but I'm assuming that's the problem.

Is there anything else I need to do to get IE to work over https on the sockjs side or the spring side?

ljmc...@gmail.com

unread,
Mar 4, 2014, 9:34:59 AM3/4/14
to soc...@googlegroups.com, ljmc...@gmail.com
Is anyone else seeing this problem????

Rossen Stoyanchev

unread,
Mar 10, 2014, 8:49:07 PM3/10/14
to soc...@googlegroups.com, ljmc...@gmail.com

Is the issue with https and IE8 only? Does it work with IE9 or IE8 without https?

There is definitely one issue I see. The sample seems to be configured with the Spring Security Java config, which by default sets the X-Frame-Options response header to DENY. IE8/9 are affected because an iframe based transport is used for HTTP streaming. So you'll want to (1) configure Spring Security to send SAMEORIGIN instead of DENY and (2) configure the "sockJsClientLibraryUrl" property of the STOMP endpoint SockJS configuration (in your WebSocketConfig). See this ticket in JIRA [1] and the following discussion as well [2].

ljmc...@gmail.com

unread,
Mar 11, 2014, 7:51:48 AM3/11/14
to soc...@googlegroups.com, ljmc...@gmail.com
Thank you for the response.

I'm able to run this over http in IE8. Unfortunately I'm unable, at this time, to setup an environment to test with IE9. I'll try your suggestion and look at the links you provided and hope that fixes the problem.

Thank you again for the help. I'll reply with the outcome later.

ljmc...@gmail.com

unread,
Mar 11, 2014, 1:09:06 PM3/11/14
to soc...@googlegroups.com, ljmc...@gmail.com
I've made the change and add a WebSecurityConfig:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().headers().addHeaderWriter(new XFrameOptionsHeaderWriter(
XFrameOptionsHeaderWriter.XFrameOptionsMode.SAMEORIGIN)).and()
.authorizeRequests()
.antMatcehrs("/sockjsProto/chatdemo/**","/chatdemo/**").permitAll.anyRequest()
.authenticated().and().anonymous();
}

Then I added a Authentication Manager bean that just calls super.

I also added the URL path to sockjs to my StompEnd point and it still doesn't connect.

It's funny, I added fiddler to see the responses on the network and when it's proxied through fiddler everything works just fine. Witch leads me to believe IE8 and my Spring server don't like each other.


 
On Monday, March 10, 2014 8:49:07 PM UTC-4, Rossen Stoyanchev wrote:
Reply all
Reply to author
Forward
0 new messages