I have a feature to display instant notification in my application like if any one send message i will send notification to other user like you got new message. For this i am using Spring MVC + Stomp + WebSocket.
In my local/test environments web sockets frames receiving and working properly over http. Prod environment is on https, frames are not receiving like http. So, notifications are not updating.
I observed one thing in websocket response: On local server user-name as email is displaying. In Prod server some random long value is displaying.
Spring Version: 4.3.5.RELEASE
Spring Security: 4.2.1.RELEASE
WebsocketConfig:
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/stomp/notify").withSockJS();
}
}
WebSecurityConfig:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.encoding.ShaPasswordEncoder;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.session.HttpSessionEventPublisher;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
AuthenticationService authenticationService;
@Value("${ssl.enabled:false}")
private boolean sslEnabled;
@Autowired
public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
ShaPasswordEncoder encoder = new ShaPasswordEncoder();
auth.userDetailsService(authenticationService).passwordEncoder(encoder);
}
@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
return new HttpSessionEventPublisher();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
if (sslEnabled) {
http.requiresChannel().antMatchers("/").requiresSecure();
}
/* authorize requests */
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/university-signup").permitAll()
.antMatchers("/fb1clicksignup").permitAll()
.antMatchers("/about").permitAll()
.antMatchers("/media").permitAll()
.antMatchers("/invite").permitAll()
.antMatchers("/public").permitAll()
.antMatchers("/reset-password").permitAll()
.antMatchers("/email-unsubscribe").permitAll()
.antMatchers("/email-subscribe").permitAll()
.antMatchers("/member")
.access("hasAnyAuthority('USER')")
.antMatchers("/member/*")
.access("hasAnyAuthority('USER')")
.and().exceptionHandling().accessDeniedPage("/");
/* login form */
http.formLogin().loginPage("/")
.loginProcessingUrl("/login")
.successHandler(customSuccessHandler())
.usernameParameter("email").passwordParameter("password")
.and().csrf();
/* logout */
http.logout().deleteCookies("remember_me_chk")
.invalidateHttpSession(true)
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/");
/* remember me*/
http.rememberMe().
key("ec2Mm2458nestOU812lingpiaza2910").
rememberMeParameter("remember-me-param").
rememberMeCookieName("remember_me_chk").
tokenValiditySeconds(31536000);
http.sessionManagement().maximumSessions(2); //a user can only have 2 active sessions
http.sessionManagement().sessionAuthenticationErrorUrl("/"); //kick the user to the homepage if session is not valid
http.sessionManagement().sessionFixation().migrateSession();
http.sessionManagement().invalidSessionUrl("/");
}
@Bean
public CustomSuccessHandler customSuccessHandler() {
return new CustomSuccessHandler();
}
}
MessagingSendingLogic:
@Autowired
private SimpMessagingTemplate messageSender;
public void sendNotification() {
messageSender.convertAndSend("/topic/messages", "Got New Message!");
}
Local/Test Server request url:
ws://mydomain.com/stomp/notify/879/z5qcek18/websocket
Local/Test Server response frames:
a["CONNECTED\nversion:1.1\nheart-beat:0,0\nuser-name:[email protected]\n\n\u0000"]
Prod Server request url:
wss://mydomain.com/stomp/notify/879/z5qcek18/websocket
Prod Server response frames:
a["CONNECTED\nversion:1.1\nheart-beat:0,0\nuser-name:110721669125112652938\n\n\u0000"]
It's my fault i have social network logins in my application. If i do direct login email is available. If i do social network login email is not available to me. So i am setting spring security principal username as oauth token. This is the reason it is displaying response frames as different. Now i am setting emailId as spring security principal username, It is working as expected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With