Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PlayFramework return absolute url in http instead of httpS?

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());
like image 487
Cyril N. Avatar asked Jun 15 '26 19:06

Cyril N.


1 Answers

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.

like image 186
James Roper Avatar answered Jun 17 '26 08:06

James Roper



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!