这些是我的配置类:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserServiceDetails customUserServiceDetails;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home", "/proc/**", "/css/**", "/js/**", "/webjars/**", "/voting-socket/topic/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Autowired
public void configureAuth(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserServiceDetails);
}
}
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/voting-socket").withSockJS();
}
}
@Configuration
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
@Override
protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
messages
.nullDestMatcher().authenticated() // 1
.simpSubscribeDestMatchers("/topic/**").permitAll()
.simpDestMatchers("/app/**").hasRole("ADMIN")
.anyMessage().denyAll(); // 2
}
}
和javascript客户端代码: function connect(vm){
let socket = new SockJS('/voting-socket');
stompClient = Stomp.over(socket);
let headers = {};
headers[headerName] = token;
stompClient.connect(headers, function (frame) {
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/voting/' + procId, function (data) {
console.log("data: " + data.body);
});
});
现在,根据我的理解,我应该能够订阅并从/voting-socket/topic
websocket端点获取数据而无需任何验证,但是我收到此错误:(来自chrome控制台的日志)
Opening Web Socket...
stomp.min.js:8 Web Socket Opened...
stomp.min.js:8 >>> CONNECT
X-CSRF-TOKEN:e0193869-8753-4eb7-b5fe-bc130796c3b1
accept-version:1.1,1.0
heart-beat:10000,10000
stomp.min.js:8 <<< ERROR
message:Failed to send message to ExecutorSubscribableChannel[clientInboundChannel]; nested exception is org.springframework.security.access.AccessDeniedException\c Access is denied
content-length:0
所以我希望这段代码能够在没有任何身份验证(登录)的情况下从/voting-socket/topic/proc/**
订阅和获取数据,并且只允许具有特定角色的登录用户将数据发送到/voting-socket/app/proc/**
。
通过一些测试,我设法使其能够删除第1行和第2行,但不确定它是否是正确的解决方案。有人可以帮我这个吗?