Websocket身份验证失败-如何将回购发送到客户端

时间:2018-12-12 19:30:06

标签: java spring-boot spring-websocket

在我的春季启动项目中,我在客户端和服务器之间建立了websocket连接。在服务器站点中使用自定义 ChannelInterceptor 的情况下,当stomp命令等于 CONNECT 时,我重写了 preSend 方法进行身份验证。

问题

用户未通过身份验证时,我无法将带有异常类的消息或消息发送到客户端应用程序。

当我不对用户进行身份验证时,我在StompSession Frame标头中的消息下方的客户端应用程序中收到:

  

无法向ExecutorSubscribableChannel [clientInboundChannel]发送消息;嵌套的异常是org.springframework.security.access.AccessDeniedException:访问被拒绝

但是我希望那里有信息,为什么会因此拒绝访问。 AuthenticationCredentialsNotFoundException BadCredentialsException

频道拦截器:

public class CustomChannelInterceptorAdapter implements ChannelInterceptor {

    @Override
    public Message<?> preSend(Message<?> message, MessageChannel channel) {
        StompHeaderAccessor accessor =
                MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
        if (accessor.getCommand().equals(StompCommand.CONNECT)) {

            WebSocketAuthenticatorService.getAuthenticatedOrFail(accessor.getLogin(), accessor.getPasscode());
            /*above and below line is just mind shortcut. getAuthenticatedOrFail will 
             return UsernamePasswordAuthenticationToken or throw specific exception 
             for ex. AuthenticationCredentialsNotFoundException or BadCredentialsException */
            if (userOK) {
                accessor.setUser(user);
            } else {
                // send response to client with exception thrown above
            }

        }
        return message;
    }
}

安全配置:

AbstractSecurityWebSocketMessageBrokerConfigurer

@Configuration
public class WebSocketAuthorizationSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {

    @Override
    protected void configureInbound(final MessageSecurityMetadataSourceRegistry messages) {
        messages.anyMessage().authenticated();
    }
}

WebSecurityConfigurerAdapter

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .httpBasic().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                .authorizeRequests().antMatchers("/register").permitAll()
                .and()
                .authorizeRequests().antMatchers("/gs-guide-websocket").permitAll()
                .and()
                .authorizeRequests().antMatchers("/actuator/info").permitAll()
                .anyRequest().denyAll();
    }

    @Bean
    public PasswordEncoder encoder() {
        return new BCryptPasswordEncoder(10);
    }
}

WebSocketMessageBrokerConfigurer

@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE + 99)
public class WebSocketAuthenticationSecurityConfig implements WebSocketMessageBrokerConfigurer {

    @Autowired
    CustomChannelInterceptorAdapter customChannelInterceptorAdapter;

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.interceptors(customChannelInterceptorAdapter);
    }
}

问题

是否可以发送带有异常信息的消息?

或者也许我应该使用 hasRole 代替 AbstractSecurityWebSocketMessageBrokerConfigurer 中的经过身份验证,并为错误创建一个单独的主题并允许每个用户在那里连接?

0 个答案:

没有答案