Принудительная маршрутизация Https для входа в систему с игровой платформой - PullRequest
21 голосов
/ 14 сентября 2011

Я хочу включить протокол https для страницы входа только моего приложения.

Возможно ли это сделать с помощью Play! без использования внешнего http-сервера?

Ответы [ 6 ]

21 голосов
/ 07 февраля 2012

Вы можете использовать перехватчик @Before для перенаправления каждого запроса, даже если пользователь вводит http: // напрямую.Ниже приведен код, который я использую (он работает при запуске без контейнера play run или при работе за внешним интерфейсом, например на Heroku).

public class HttpsRequired extends Controller {
    /** Called before every request to ensure that HTTPS is used. */
    @Before
    public static void redirectToHttps() {
        //if it's not secure, but Heroku has already done the SSL processing then it might actually be secure after all
        if (!request.secure && request.headers.get("x-forwarded-proto") != null) {
            request.secure = request.headers.get("x-forwarded-proto").values.contains("https");
        }

        //redirect if it's not secure
        if (!request.secure) {
            String url = redirectHostHttps() + request.url;
            System.out.println("Redirecting to secure: " + url);
            redirect(url);
        }
    }

    /** Renames the host to be https://, handles both Heroku and local testing. */
    @Util
    public static String redirectHostHttps() {
        if (Play.id.equals("dev")) {
            String[] pieces = request.host.split(":");
            String httpsPort = (String) Play.configuration.get("https.port");
            return "https://" + pieces[0] + ":" + httpsPort; 
        } else {
            if (request.host.endsWith("domain.com")) {
                return "https://secure.domain.com";
            } else {
                return "https://" + request.host;
            }
        }
    }    
}
6 голосов
/ 21 октября 2013

Вот пример, который работает с Java Play 2.1.1 и Heroku.

public class ForceHttps extends Action<Controller> {

    // heroku header
    private static final String SSL_HEADER = "x-forwarded-proto";

    @Override
    public Result call(Context ctx) throws Throwable {
        final Result result;
        if (Play.isProd() && !isHttpsRequest(ctx.request())) {
            result = redirect("https://" + ctx.request().host()
                    + ctx.request().uri());
        }
        else {
            // let request proceed
            result = this.delegate.call(ctx);
        }
        return result;
    }

    private static boolean isHttpsRequest(Request request) {
        // heroku passes header on
        return request.getHeader(SSL_HEADER) != null
                && request.getHeader(SSL_HEADER)
                        .contains("https");
    }

}

Затем к любым контроллерам, которые вы хотите проверить на https, добавьте @With (ForceHttps.class). Или, если вы хотите, чтобы все контроллеры проверяли, добавьте класс HttpsController, расширяющий Controller, и пусть все ваши классы расширяют HttpsController.

, например

@With(ForceHttps.class)
public class HttpsController extends Controller {

}
3 голосов
/ 14 мая 2014

Если вы используете AWS, вы можете завершить HTTPS на балансировщике нагрузки и использовать фильтр для перенаправления HTTP-соединения на HTTPS.

AWS Conf:

443 (балансировщик нагрузки) ----------> 80 (сервер)

80 (балансировщик нагрузки) ----------> 80 (сервер)

Фильтр:

object HTTPSRedirectFilter extends Filter with Logging {

    def apply(nextFilter: (RequestHeader) => Future[SimpleResult])(requestHeader: RequestHeader): Future[SimpleResult] = {
        //play uses lower case headers.
        requestHeader.headers.get("x-forwarded-proto") match {
            case Some(header) => {
                if ("https" == header) {
                    nextFilter(requestHeader).map { result =>
                        result.withHeaders(("Strict-Transport-Security", "max-age=31536000"))
                    }
                } else {
                    Future.successful(Results.Redirect("https://" + requestHeader.host + requestHeader.uri, 301))
                }
            }
            case None => nextFilter(requestHeader)
        }
    }
}
3 голосов
/ 19 октября 2011

Я думаю, что вы можете проверить в контроллере request.secure == true и затем перенаправить на https.

2 голосов
/ 14 сентября 2011

Вы должны быть в состоянии. Сделайте следующее:

  1. Настройте http.port и https.port в файле application.config
  2. Пользователь @@ {Controller.action (). Secure ()}, когда вам нужно указать на защищенную страницу. Используйте @@, чтобы сгенерировать полный URL (включая https) и безопасный для подсказки, чтобы воспроизвести нужный протокол HTTPS

Это должно работать

0 голосов
/ 19 сентября 2011

Это не представляется возможным с точки зрения контроллера.Из шаблона Pere решение работает, но при этом генерируется только URL-адрес https из шаблона.

Если пользователь получает доступ к действию входа в систему, введя его вручную или перейдя по ссылке на URL-адрес http, похоже, чтоспособ принудительного применения / перенаправления на https.

Наилучшим способом, по-видимому, является внешний прокси-сервер.

...