Nginx 反向代理 Websocket 身份验证 - HTTP 403

标签 nginx spring-security websocket spring-boot

我使用 Nginx 作为 Spring boot 应用程序的反向代理。我还将 Websockets 与 sockjs 和 stomp 消息一起使用。

这是上下文配置。

<websocket:message-broker application-destination-prefix="/app">
    <websocket:stomp-endpoint path="/localization" >
        <websocket:sockjs/>
    </websocket:stomp-endpoint>
    <websocket:simple-broker prefix="/topic" />
</websocket:message-broker>

这是客户端代码:

var socket = new SockJS(entryPointUrl);
var stompClient = Stomp.over(socket);

var _this = this;

stompClient.connect({}, function () {
    stompClient.subscribe('/app/some-url', function (message) {
         // do some stuff
    });
});

我还用Spring Security来保护一些内容。

@Configuration
@Order(4)
public static class FrontendSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/js/**", "/css/**", "/webjars/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().loginPage("/login").permitAll()
                .and()
                .logout().permitAll();
    }

}

一切都很好,预计当我在 Nginx 反向代理后面运行这个应用程序时。这是反向配置:

    proxy_pass http://testsysten:8080;

    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    # WebSocket support (nginx 1.4)
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $http_connection;

    # Max body size
    client_max_body_size 10M;

连接始终失败并显示 HTTP 403 代码。

我使用的是1.9.7版本。

您知道为什么客户端未通过身份验证吗?

我知道类似的问题,例如 this one但这些解决方案根本不起作用。

更新

我设法通过 HTTP 运行该应用程序。我需要通过CSRF Nginx 配置中的 token 。新配置是:

    proxy_pass http://testsysten:8080;

    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    # Pass the csrf token (see https://de.wikipedia.org/wiki/Cross-Site-Request-Forgery)
    # Default in Spring Boot
    proxy_pass_header X-XSRF-TOKEN;

    # WebSocket support (nginx 1.4)
    proxy_http_version 1.1;

唯一缺少的是通过 HTTPS 进行重定向。在 Spring 日志中可以看到以下条目:

o.s.w.s.s.t.h.DefaultSockJsService - Processing transport request: GET http://testsystem:80/localization/226/3mbmu212/websocket

似乎 Nginx 代理需要重写到正确的端口。

最佳答案

我自己解决了这个问题。基本上,如果你想使用 Websocket 和 Spring Security,Nginx 需要传递一些额外的 header 值。需要将以下行添加到 Nginx 配置中的 location 部分:

    # Pass the csrf token (see https://de.wikipedia.org/wiki/Cross-Site-Request-Forgery)
    # Default in Spring Boot and required. Without it nginx suppresses the value
    proxy_pass_header X-XSRF-TOKEN;

    # Set origin to the real instance, otherwise a of Spring security check will fail
    # Same value as defined in proxy_pass
    proxy_set_header Origin "http://testsysten:8080";  

关于Nginx 反向代理 Websocket 身份验证 - HTTP 403,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34136630/

相关文章:

docker - 无法访问 nginx 容器后面的容器化服务

uwsgi 中的 nginx 负载均衡

java - 如何在没有登录页面的情况下使用简单的 Spring Security AuthenticationProvider?

c# - 从 websocket 接收字节 - Windows 8 应用程序

c# - 使用 WebSocket 在 Java 和 C# 桌面应用程序之间进行通信?

ruby-on-rails - 在 Rails 中使用 unicorn、nginx 和 capistrano 设置虚拟主机

nginx - Spring Boot 和 Nginx 集成

java - 根据权限从数据库中获取数据

java - spring security oauth2发布限制

ssl - HiveMQ 中的 Websockets 不工作 - 日志中没有任何内容