I've implemented a project in Play!Framework with NGinx using only https.
Everything works fine, the SSL is well recognized and I can use my app from anywhere but when Play! returns an absolute URL, it's in http, not https.
This is problematic, and I don't know where the problem is. I tried to start Play with -Dhttps.port=XXXX instead of -Dhttp.port=XXXX but it didn't changed the output of "http" instead of "https".
I'm suspecting an Nginx bad configuration (a parameter I forgot?).
Here's my sites-enabled/website config file :
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;
}
}
What am I missing?
Update: Here's the code that generate the absolute url :
controllers.routes.Pages.loginToken(getToken()).absoluteURL(play.mvc.Http.Context.current().request());
What you actually need is to add the scheme in the X-Forwarded-Proto header. None of the X-Forwarded-* headers are standard, but the convention (or defacto standard) is to put the scheme in X-Forwarded-Proto, and Play has support this since 2.3.0:
https://github.com/playframework/playframework/pull/1823
So, if you add the following to your nginx config:
proxy_set_header X-Forwarded-Proto $scheme;
And have configured Play to trust the x forwarded headers, by adding this to your application.conf:
trustxforwarded=true
Then RequestHeader.secure will return true.
Note that in Play 2.4, we've improved the support dramatically, implementing the full specification for the new standard Forwarded header, as well as being able to specify which hosts to trust forwarded headers from.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With