Аутентификация пользователя WebSocket в Spring Boot 2 + SockJS - PullRequest
0 голосов
/ 12 февраля 2019

Использовал это руководство.

Но тут я столкнулся с тем, что мне нужно ввести пользователя в контроллер.И я могу получить это из токена JWT.Если все понятно и сделано с приложением REST и JWT, то я не понимаю, как получить пользователя в сокеты и вообще проверить, авторизован ли он.Как это сделать?

Вот код, который доступен:

Конфигурация сокета:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    private final TokenUtils tokenUtils;

    private static final String ENDPOINT = "/websocket";

    private static final String TOPIC_CHAT = "/secured/client";
    private static final String TOPIC_QUEUE = "/secured/queue";
    private static final String TOPIC_OPERATOR = "/secured/operator";

    public WebSocketConfig(TokenUtils tokenUtils) {
        this.tokenUtils = tokenUtils;
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker(TOPIC_CHAT, TOPIC_QUEUE, TOPIC_OPERATOR);
        config.setApplicationDestinationPrefixes("/ws");
        config.setUserDestinationPrefix("/secured/user");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint(ENDPOINT)
                .setAllowedOrigins("*")
                .addInterceptors(new WebSocketHandshakeInterceptor()).withSockJS();
    }

}

Конфиг секюрити для сокетов:

@Configuration
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {

    @Override
    protected boolean sameOriginDisabled() {
        return true;
    }

    @Override
    protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
        messages.simpTypeMatchers(
                SimpMessageType.CONNECT,
                SimpMessageType.DISCONNECT).permitAll().anyMessage().permitAll()
                .simpDestMatchers("/secured/**").authenticated().anyMessage().authenticated();
    }
}

Security Config:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UnauthorizedEntryPoint unauthorizedEntryPoint;

    @Autowired
    private TokenAuthenticationProvider tokenAuthenticationProvider;

    private static final RequestMatcher PUBLIC_URLS = new OrRequestMatcher(
            new AntPathRequestMatcher("/"),
            new AntPathRequestMatcher("/index"),
            new AntPathRequestMatcher("/index.html"),
            new AntPathRequestMatcher("/resource/**"),
            new AntPathRequestMatcher("/favicon.ico"),
            new AntPathRequestMatcher("/actuator/**"),
            new AntPathRequestMatcher("/h2-console/**"),
            new AntPathRequestMatcher("/**/favicon.ico"),
            new AntPathRequestMatcher("/webjars/**"),
            new AntPathRequestMatcher("/websocket/**"),
            new AntPathRequestMatcher("/api/v1/download/**"),
            new AntPathRequestMatcher("/api/v1/owner/auth/**"),
            new AntPathRequestMatcher("/api/v1/operator/auth/**")
    );

    private static final RequestMatcher PROTECTED_URLS = new NegatedRequestMatcher(PUBLIC_URLS);

    @Override
    protected void configure(AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(this.tokenAuthenticationProvider);
    }

    @Override
    public void configure(WebSecurity web) {
        web.ignoring().requestMatchers(PUBLIC_URLS);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.cors().and()
                .csrf().disable()
                .formLogin().disable()
                .httpBasic().disable()
                .logout().disable();

        http.headers().frameOptions().disable();

        http.authorizeRequests()
                .requestMatchers(PUBLIC_URLS)
                .permitAll();

        http.authorizeRequests()
                .antMatchers("/secured/**").authenticated();

        http
                .sessionManagement()
                .sessionCreationPolicy(STATELESS)
                .and()
                .exceptionHandling()
                .defaultAuthenticationEntryPointFor(unauthorizedEntryPoint, PROTECTED_URLS)
                .and()
                .authenticationProvider(tokenAuthenticationProvider)
                .addFilterBefore(tokenAuthenticationFilter(), AnonymousAuthenticationFilter.class)
                .authorizeRequests()
                .requestMatchers(PROTECTED_URLS)
                .authenticated();

    }

    @Bean
    TokenAuthenticationFilter tokenAuthenticationFilter() throws Exception {
        final TokenAuthenticationFilter filter = new TokenAuthenticationFilter(PROTECTED_URLS);
        filter.setAuthenticationManager(authenticationManager());
        filter.setAuthenticationSuccessHandler(new AuthenticationSuccessHandler());
        filter.setAuthenticationFailureHandler(new AuthenticationFailureHandler());
        return filter;
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration configuration = new CorsConfiguration().applyPermitDefaultValues();
        configuration.addAllowedMethod(HttpMethod.PUT);
        configuration.addAllowedMethod(HttpMethod.DELETE);
        configuration.addAllowedMethod(HttpMethod.OPTIONS);
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

}
...