Использовал это руководство.
Но тут я столкнулся с тем, что мне нужно ввести пользователя в контроллер.И я могу получить это из токена 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();
}
}