PlayFramework return 绝对 url 在 http 而不是 httpS 中?
PlayFramework return absolute url in http instead of httpS?
我已经在 Play!Framework 中使用 NGinx 仅使用 https 实现了一个项目。
一切正常,SSL 得到很好的识别,我可以从任何地方使用我的应用程序,但在播放时除外! returns 绝对 URL,它在 http,而不是 https。
这个有问题,不知道问题出在哪里。
我尝试使用 -Dhttps.port=XXXX 而不是 -Dhttp.port=XXXX 开始播放,但它并没有改变 "http" 而不是 "https".[=15= 的输出]
我怀疑 Nginx 配置错误(我忘记了一个参数?)。
这是我的 sites-enabled/website
配置文件:
proxy_buffering off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme "https"; # I also tried $scheme without any luck
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
server {
listen 80;
server_name my.website.com;
return 301 https://my.website.com;
}
upstream my-backend {
server 127.0.0.1:9100;
}
server {
listen 443;
ssl on;
root /var/www/website/errors/;
# http://www.selfsignedcertificate.com/ is useful for development testing
ssl_certificate /etc/nginx/ssl/my.website.com.crt;
ssl_certificate_key /etc/nginx/ssl/my.website.com.key;
# From https://bettercrypto.org/static/applied-crypto-hardening.pdf
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # not possible to do exclusive
ssl_ciphers 'EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!ECDSA:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA';
add_header Strict-Transport-Security max-age=15768000; # six months
# use this only if all subdomains support HTTPS!
# add_header Strict-Transport-Security "max-age=15768000; includeSubDomains"
keepalive_timeout 70;
server_name my.website.com;
location / {
#proxy_pass http://my-backend;
proxy_pass http://127.0.0.1:9100;
}
location ~ /\.git {
deny all;
}
error_page 502 @maintenance;
location @maintenance {
rewrite ^(.*)$ /error502.html break;
}
}
我错过了什么?
更新:这是生成绝对url的代码:
controllers.routes.Pages.loginToken(getToken()).absoluteURL(play.mvc.Http.Context.current().request());
absoluteURL
有几个重载。您正在使用这个:
public String absoluteURL(Http.Request request) {
return absoluteURL(request.secure(), request.host());
}
问题在于,由于您是通过 nginx 反向代理到 Play,Play 实际上是通过 HTTP 而不是 HTTPS 接收所有请求。这意味着 request.secure()
为假,并且 absoluteURL
将 return 包含 http://...
.
的 URL
相反,在其中一个重载中手动将 secure
设置为 true
:
controllers.routes.Pages.loginToken(getToken()).absoluteURL(play.mvc.Http.Context.current().request(), true);
此外,我通常做的是为 secure
设置一个配置变量,这样它可以在本地开发时生成非 https URLs。
在application.conf中:
application.secure = false # for local dev
在生产环境中,我在启动应用程序时添加了命令行选项 -Dapplication.secure=true
,以覆盖 application.conf
中的值。
然后生成 URL 将如下所示:
controllers.routes.Pages.loginToken(getToken()).absoluteURL(
play.mvc.Http.Context.current().request(),
play.Play.application().configuration().getBoolean("application.secure", true) // default to true
);
您真正需要的是在X-Forwarded-Proto
header中添加方案。 X-Forwarded-*
header 中的 None 是标准的,但是惯例(或事实上的标准)是将方案放在 X-Forwarded-Proto
中,Play 从 2.3.0 开始支持这个:
https://github.com/playframework/playframework/pull/1823
因此,如果您将以下内容添加到您的 nginx 配置中:
proxy_set_header X-Forwarded-Proto $scheme;
并已将 Play 配置为信任 x 转发的 headers,方法是将其添加到您的 application.conf
:
trustxforwarded=true
然后 RequestHeader.secure
将 return 为真。
请注意,在 Play 2.4 中,我们显着改进了支持,实现了新标准的完整规范 Forwarded
header,并且能够指定要信任转发的主机 header来自.
我已经在 Play!Framework 中使用 NGinx 仅使用 https 实现了一个项目。
一切正常,SSL 得到很好的识别,我可以从任何地方使用我的应用程序,但在播放时除外! returns 绝对 URL,它在 http,而不是 https。
这个有问题,不知道问题出在哪里。 我尝试使用 -Dhttps.port=XXXX 而不是 -Dhttp.port=XXXX 开始播放,但它并没有改变 "http" 而不是 "https".[=15= 的输出]
我怀疑 Nginx 配置错误(我忘记了一个参数?)。
这是我的 sites-enabled/website
配置文件:
proxy_buffering off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme "https"; # I also tried $scheme without any luck
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
server {
listen 80;
server_name my.website.com;
return 301 https://my.website.com;
}
upstream my-backend {
server 127.0.0.1:9100;
}
server {
listen 443;
ssl on;
root /var/www/website/errors/;
# http://www.selfsignedcertificate.com/ is useful for development testing
ssl_certificate /etc/nginx/ssl/my.website.com.crt;
ssl_certificate_key /etc/nginx/ssl/my.website.com.key;
# From https://bettercrypto.org/static/applied-crypto-hardening.pdf
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # not possible to do exclusive
ssl_ciphers 'EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!ECDSA:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA';
add_header Strict-Transport-Security max-age=15768000; # six months
# use this only if all subdomains support HTTPS!
# add_header Strict-Transport-Security "max-age=15768000; includeSubDomains"
keepalive_timeout 70;
server_name my.website.com;
location / {
#proxy_pass http://my-backend;
proxy_pass http://127.0.0.1:9100;
}
location ~ /\.git {
deny all;
}
error_page 502 @maintenance;
location @maintenance {
rewrite ^(.*)$ /error502.html break;
}
}
我错过了什么?
更新:这是生成绝对url的代码:
controllers.routes.Pages.loginToken(getToken()).absoluteURL(play.mvc.Http.Context.current().request());
absoluteURL
有几个重载。您正在使用这个:
public String absoluteURL(Http.Request request) {
return absoluteURL(request.secure(), request.host());
}
问题在于,由于您是通过 nginx 反向代理到 Play,Play 实际上是通过 HTTP 而不是 HTTPS 接收所有请求。这意味着 request.secure()
为假,并且 absoluteURL
将 return 包含 http://...
.
相反,在其中一个重载中手动将 secure
设置为 true
:
controllers.routes.Pages.loginToken(getToken()).absoluteURL(play.mvc.Http.Context.current().request(), true);
此外,我通常做的是为 secure
设置一个配置变量,这样它可以在本地开发时生成非 https URLs。
在application.conf中:
application.secure = false # for local dev
在生产环境中,我在启动应用程序时添加了命令行选项 -Dapplication.secure=true
,以覆盖 application.conf
中的值。
然后生成 URL 将如下所示:
controllers.routes.Pages.loginToken(getToken()).absoluteURL(
play.mvc.Http.Context.current().request(),
play.Play.application().configuration().getBoolean("application.secure", true) // default to true
);
您真正需要的是在X-Forwarded-Proto
header中添加方案。 X-Forwarded-*
header 中的 None 是标准的,但是惯例(或事实上的标准)是将方案放在 X-Forwarded-Proto
中,Play 从 2.3.0 开始支持这个:
https://github.com/playframework/playframework/pull/1823
因此,如果您将以下内容添加到您的 nginx 配置中:
proxy_set_header X-Forwarded-Proto $scheme;
并已将 Play 配置为信任 x 转发的 headers,方法是将其添加到您的 application.conf
:
trustxforwarded=true
然后 RequestHeader.secure
将 return 为真。
请注意,在 Play 2.4 中,我们显着改进了支持,实现了新标准的完整规范 Forwarded
header,并且能够指定要信任转发的主机 header来自.