如何解决nginx反向代理后面的Spring Boot拒绝标头值“??????”
我有一个小的 Spring Boot 应用程序,我想在我的服务器上本地运行,这个服务器运行其他一些东西,所以这些服务都在一个 nginx 反向代理之后,这是端口转发出我的网络指向的DNS。
我已在服务器上运行我的应用程序并通过 192.168.x.x:80 访问它工作正常。但是,当我通过反向代理访问它并通过我的域访问它时,它会中断。
中断的性质似乎是春季安全性,因为它应该将我重定向到我的 /login 页面,但事实并非如此。我在服务器控制台中收到的消息是:
org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the header value "??????" is not allowed.
这让我怀疑反向代理对标头执行某些操作时发生了一些有趣的事情,但我不是这方面的专家。
我的nginx设置如下:
server{
location / {
proxy_pass_header Authorization;
proxy_pass http://$upstream;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Connection ^`^| ^`^};
proxy_buffering off;
client_max_body_size 0;
proxy_read_timeout 36000s;
proxy_redirect off;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/myapp.mydomain.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/myapp.mydomain.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = myapp.mydomain.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
return 404; # managed by Certbot
}
我在 server.use-forward-headers=true
中添加了 application.properties
但这似乎没有任何作用。
如果您能对此提供帮助,将不胜感激,谢谢。
解决方法
默认使用 StrictHttpFirewall。此实现拒绝看似恶意的请求,例如非 ASCII 字符或没有 MIME 标头编码的字符串。如果对您的需求过于严格,那么您可以自定义拒绝哪些类型的请求。
这是 Spring Boot 2.4 升级到的 Spring Security 5.4 中的标准行为。这是mentioned in the Spring Security documentation,它也提供了一些information about configuring the behaviour
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
@Override
public void configure(WebSecurity web) {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowUrlEncodedSlash(true);
firewall.setAllowBackSlash(true);
firewall.setAllowUrlEncodedPercent(true);
firewall.setAllowUrlEncodedPeriod(true);
firewall.setAllowSemicolon(true);
// Allow UTF-8 values
Pattern allowed = Pattern.compile("[\\p{IsAssigned}&&[^\\p{IsControl}]]*");
firewall.setAllowedHeaderValues((header) -> {
String parsed = new String(header.getBytes(ISO_8859_1),UTF_8);
return allowed.matcher(parsed).matches();
});
web.httpFirewall(firewall);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。