Я собираюсь добавить обработчик WebSocket в свое приложение Spring Boot 3. Но наряду с этим я хочу защитить его с помощью OAuth. Для этого есть уже подготовленный сервер авторизации. Важно то, что я хочу использовать чистый WebSocket вместо STOMP, поэтому я буду использовать @EnableWebSocket
вместо @EnableWebSocketMessageBroker
, потому что мне не нужна вся та сложность и функциональность, которые обеспечивает обмен сообщениями через WebSocket, поддерживаемый брокером.
Возникает вопрос: как в этом случае можно реализовать проверку OAuth? Должен ли я реализовать перехватчик? Должен ли я выполнять проверку во время рукопожатия? Похоже, @EnableWebSocketSecurity
не подходит для этого случая, поскольку это приемлемо, когда вы используете обмен сообщениями, поддерживаемый брокером, через WebSocket.
Решение довольно простое, но требует некоторых пояснений, поэтому мне пришлось написать об этом небольшую статью. Ссылку прикреплю в конце. Здесь я постараюсь объяснить вкратце.
Если мы используем чистые соединения WebSocket, перед установкой соединения WebSocket выполняется процесс установления связи. Рукопожатие выполняется с использованием HTTP/HTTPS (в зависимости от ваших настроек). После выполнения рукопожатия соединение переключается на WebSocket.
Поскольку рукопожатие выполняется с использованием HTTP/HTTPS, мы можем удовлетворить потребности безопасности с помощью обычной конфигурации безопасности, которую мы используем для защиты конечных точек. Изменения безопасности будут выполнены во время рукопожатия. Если проверка безопасности не пройдена, рукопожатие завершится неудачей и соединение WebSocket не будет установлено.
За исключением зависимости WebSocket, нам нужна только обычная зависимость безопасности и зависимость для подключения к серверу авторизации OAuth:
implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-websocket'
В конфигурации мы просто настраиваем проверку OAuth-сервера и описываем правила безопасности для нужной конечной точки.
@Configuration
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(registry -> registry
.requestMatchers("/websocket/endpoint").hasAuthority("SCOPE_my.scope")
)
.oauth2ResourceServer(configurer -> configurer
.jwt(withDefaults())
)
.build();
}
}
В файле свойств приложения нам необходимо настроить свойства наших подключений к серверу авторизации. В моем случае сервер находится на http://auth-server:9000
.
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: http://auth-server:9000
Вот и все. Теперь во время рукопожатия будут применяться описанные правила безопасности. Описанные свойства приложения будут использоваться при подключении к серверу авторизации. После выполнения рукопожатия будет установлено соединение WebSocket.
Ссылка на статью (пошаговое руководство): https://medium.com/@HereAndBeyond/bf479327339f