问题
I used play framework version 2.2.3 and I run activator using following command for accessing site using https.
./activator run -Dhttp.port=disabled -Dhttps.port=9043
and I typed URL in browser as below
https://localhost:9043/signin
Then it work fine and it redirects to https. But problem is that when I changed my URL as below
http://localhost:9043/signin
then I want to redirect above URL to https, how should this handled in play framework?
回答1:
as of play 2.6.x it's now supported by a configuration
play.filters.enabled += play.filters.https.RedirectHttpsFilter
回答2:
There are two question in there
- How do we detect SSL in Play?
For Play 2.2 myself, I use a reverse proxy to handle SSL which will automatically add a request header "X-Forwarded-Proto". I then check that header to verify that the connect is coming in via SSL.
String protocolHeaders = context.request().getHeader("X-Forwarded-Proto");
if(protocolHeaders != null) {
String[] split = protocolHeaders.split(",");
for(int i=0;i<split.length;i++) {
if(split[i].trim().equalsIgnoreCase("https")) {
return delegate.call(context);
}
}
}
I upgrading Play is an option, with Play 2.3 https detection is automatic, the header class has a built in secure() method which detects SSL and handle reverse proxied SSL as well.
https://www.playframework.com/documentation/2.3.x/api/java/play/mvc/Http.RequestHeader.html#secure()
- How to handle redirecting insecure (http) requests to secure (https)?
I used an Action which I annotated my controllers (or base controllers) with.
public class SslEnforcerAction extends play.mvc.Action<SslEnforced> {
@Override
public Promise<SimpleResult> call(Context context) throws Throwable {
Logger.info("Running ssl enforcer");
String sslEnabled = Play.application().configuration().getString("app.ssl.enabled");
if(!StringUtils.equals(sslEnabled, "true")) {
return delegate.call(context);
}
Logger.info("X-Forwarded-Proto : {}", context.request().getHeader("X-Forwarded-Proto"));
String protocolHeaders = context.request().getHeader("X-Forwarded-Proto");
if(protocolHeaders != null) {
String[] split = protocolHeaders.split(",");
for(int i=0;i<split.length;i++) {
if(split[i].trim().equalsIgnoreCase("https")) {
return delegate.call(context);
}
}
}
Controller.flash("success", "For your security we've switched to SSL");
String target = "";
if(configuration.response() == SslEnforcedResponse.SELF) {
target = "https://" + context.request().host() + context.request().uri();
}
else {
target = controllers.my.dashboard.routes.DashboardController.index().absoluteURL(true, context._requestHeader());
}
//if we are here then ssl is enabled and the request wasn't ssl, so reject them
return Promise.pure(Controller.redirect(target));
}
}
/** allow controllers to send insure requests to themselves to dashboard */
public enum SslEnforcedResponse {
SELF,
DASHBOARD
}
@With(SslEnforcerAction.class)
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface SslEnforced {
SslEnforcedResponse response() default SslEnforcedResponse.SELF;
}
@SslEnforced
public class Application extends Controller {
....
}
回答3:
For those of us who run Play 2.5 and keep landing on this page 4 years later:
In build.sbt add:
libraryDependencies += "com.github.enalmada" %% "play-https-redirect" % "1.0.2"
Create a Filters.java file inside the app/ folder. The following example redirects and also zips the response, you can delete the Gzip bits if you need:
import com.github.enalmada.filters.HttpsRedirectFilter;
import play.filters.gzip.GzipFilter;
import play.http.HttpFilters;
import play.mvc.EssentialFilter;
import javax.inject.Inject;
public class Filters implements HttpFilters {
private EssentialFilter[] filters;
@Inject
public Filters(GzipFilter gzipFilter, HttpsRedirectFilter httpsRedirectFilter) {
filters = new EssentialFilter[] { gzipFilter.asJava(), httpsRedirectFilter.asJava()};
}
public EssentialFilter[] filters() {
return filters;
}
}
In application.conf, root level, add:
httpsRedirect {
enabled=true
modes=["Prod", "Dev"]
excluded=["/url-to-exclude"]
hsts {
enabled=true
maxAge=31536000
preload = true
includeSubDomains = true
}
}
play.filters.enabled += play.filters.https.RedirectHttpsFilter
Download play-https-redirect example project and see it working in your localhost.
来源:https://stackoverflow.com/questions/25426209/play-framework-redirect-http-to-https