I have an Angular 2 Application using ng2-stomp-service. It works with Spring WebSocket without security.
But I cannot get Authentication credential to send over to Spring Security. Here is the config in Spring Security:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/demo-websocket/info").permitAll()
.antMatchers("/demo-websocket/**/websocket").permitAll()
.antMatchers("/info", "/health").permitAll()
.antMatchers("/info", "/health").permitAll()
.antMatchers("/api/**", "/advisor").hasRole("USER")
.anyRequest().authenticated();
}
}
Here is the Spring WebSocket Security Setup:
@Configuration
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
@Override
protected void configureInbound(MessageSecurityMetadataSourceRegistry registry) {
registry
.simpTypeMatchers(CONNECT).permitAll()
.simpTypeMatchers(UNSUBSCRIBE, DISCONNECT).permitAll()
.simpMessageDestMatchers("/app/**").permitAll()
.simpSubscribeDestMatchers("/topic/**").permitAll()
.anyMessage().authenticated()
;
}
@Override
protected boolean sameOriginDisabled() {
//disable CSRF for websockets for now...
return true;
}
}
Notice that "permitAll()" is being used such that it works without Authentication. However, if ".simpMessageDestMatchers("/app/").permitAll()" is changed to ".simpMessageDestMatchers("/app/").authenticated()", it won't work.
Here is the Angular 2 setup:
this.stomp.configure({
host: `http://${config.host}:${config.port}/demo-websocket`,
debug: true,
queue: {'init': false},
headers: {
login: 'user',
passcode: 'password',
authorization: `Basic ${this.calcBase64UserPassword()}`
},
});
Angular 2 code for connecting to Spring WebSocket:
this.subject = new Subject<Greeting>();
this.stomp.startConnect().then(() => {
this.stomp.done('init');
console.log('Connect established.');
this.connected = true;
this.subscription = this.stomp.subscribe('/topic/greetings', this.response.bind(this));
});
Angular 2 code for sending a message via web socket:
send(messageText: string): void {
if (this.connected) {
const message = new DomainMessage(this.msgId, messageText);
this.stomp.send('/app/hello', message, {
login: 'user',
passcode: 'password'
});
}
}
Angular 2 code for calculating Basic Authentication Base 64 header:
private calcBase64UserPassword(username = config.username, password = config.password): string {
const result = btoa(`${username}:${password}`);
console.log (`${result}`);
return result;
}