§組み込みHTTPフィルター
Playは、アプリケーションのHTTP動作を変更できるいくつかの標準フィルターを提供しています。 独自のフィルターは、JavaまたはScalaのいずれかで記述することもできます。
§デフォルトフィルター
Playには、設定を介して定義された、有効化されたデフォルトのフィルターセットが付属するようになりました。プロパティplay.http.filters
がnullの場合、デフォルトはplay.api.http.EnabledFilters
になり、play.filters.enabled
設定プロパティに完全修飾クラス名で定義されたフィルターがロードされます。
Play自体では、play.filters.enabled
は空のリストです。しかし、フィルターライブラリはPlayFilters
というAutoPluginとしてsbtに自動的にロードされ、play.filters.enabled
プロパティに以下の値を追加します。
play.filters.csrf.CSRFFilter
play.filters.headers.SecurityHeadersFilter
play.filters.hosts.AllowedHostsFilter
つまり、新しいプロジェクトでは、CSRF保護(ScalaCsrf / JavaCsrf)、SecurityHeaders、およびAllowedHostsFilterがすべて自動的に定義されます。
デフォルトリストに追加するには、+=
を使用します。
play.filters.enabled+=MyFilter
以前にplay.api.http.DefaultHttpFilters
を拡張して独自のフィルターを定義していた場合は、コード内でEnabledFilters
と独自のフィルターを組み合わせることもできます。
- Java
-
import java.util.ArrayList; import java.util.List; import javax.inject.Inject; import play.api.http.EnabledFilters; import play.filters.cors.CORSFilter; import play.http.DefaultHttpFilters; import play.mvc.EssentialFilter; public class Filters extends DefaultHttpFilters { @Inject public Filters(EnabledFilters enabledFilters, CORSFilter corsFilter) { super(combine(enabledFilters.asJava().getFilters(), corsFilter.asJava())); } private static List<EssentialFilter> combine( List<EssentialFilter> filters, EssentialFilter toAppend) { List<EssentialFilter> combinedFilters = new ArrayList<>(filters); combinedFilters.add(toAppend); return combinedFilters; } }
- Scala
-
import javax.inject.Inject import play.api.http.DefaultHttpFilters import play.api.http.EnabledFilters import play.filters.cors.CORSFilter class Filters @Inject() (enabledFilters: EnabledFilters, corsFilter: CORSFilter) extends DefaultHttpFilters(enabledFilters.filters :+ corsFilter: _*)
それ以外の場合、ルートにFilters
クラスがあるか、play.http.filters
が明示的に定義されている場合、後述のEnabledFilters
機能よりも優先されます。
§デフォルトフィルターのテスト
複数のフィルターが有効になっているため、すべてのテストがパスし、リクエストが有効であることを確認するために、機能テストをわずかに変更する必要がある場合があります。たとえば、Host
HTTPヘッダーがlocalhost
に設定されていないリクエストは、AllowedHostsFilterを通過せず、代わりに400 Forbidden応答を返します。
§AllowedHostsFilterを使用したテスト
AllowedHostsFilterフィルターが自動的に追加されるため、機能テストではHost HTTPヘッダーを追加する必要があります。
FakeRequest
またはHelpers.fakeRequest
を使用している場合、Host
HTTPヘッダーは自動的に追加されます。play.mvc.Http.RequestBuilder
を使用している場合は、ヘッダーを手動で追加する独自の行を追加する必要がある場合があります。
Http.RequestBuilder request =
new Http.RequestBuilder()
.method(GET)
.header(Http.HeaderNames.HOST, "localhost")
.uri("/xx/Kiwi");
§CSRFFilterを使用したテスト
CSRFFilterフィルターが自動的に追加されるため、CSRF.formField
を含むTwirlテンプレートをレンダリングするテスト、つまり
@(userForm: Form[UserData])(implicit request: RequestHeader, m: Messages)
<h1>user form</h1>
@request.flash.get("success").getOrElse("")
@helper.form(action = routes.UserController.userPost()) {
@helper.CSRF.formField
@helper.inputText(userForm("name"))
@helper.inputText(userForm("age"))
<input type="submit" value="submit"/>
}
には、リクエストにCSRFトークンを含める必要があります。Scala APIでは、play.api.test.CSRFTokenHelper._
をインポートすることでこれを実行します。これにより、play.api.test.FakeRequest
がwithCSRFToken
メソッドで強化されます。
import org.specs2.mutable.Specification
import play.api.inject.guice.GuiceApplicationBuilder
import play.api.test.CSRFTokenHelper._
import play.api.test.FakeRequest
import play.api.test.Helpers._
import play.api.test.WithApplication
class UserControllerSpec extends Specification {
"UserController GET" should {
"render the index page from the application" in new WithApplication() {
override def running() = {
val controller = app.injector.instanceOf[UserController]
val request = FakeRequest().withCSRFToken
val result = controller.userGet().apply(request)
status(result) must beEqualTo(OK)
contentType(result) must beSome("text/html")
}
}
}
}
Java APIでは、play.mvc.Http.RequestBuilder
インスタンスでCSRFTokenHelper.addCSRFToken
を呼び出すことでこれを実行します。
Http.RequestBuilder request = new Http.RequestBuilder().method(POST).uri("/xx/Kiwi");
request = CSRFTokenHelper.addCSRFToken(request);
§デフォルトフィルターの無効化
フィルターを無効にする最も簡単な方法は、application.conf
のplay.filters.disabled
リストに追加することです。
play.filters.disabled+=play.filters.hosts.AllowedHostsFilter
これは、デフォルトフィルターを通過させたくない機能テストがある場合に役立つ場合があります。
デフォルトフィルターを削除するには、リスト全体を手動で設定できます。
play.filters.enabled=[]
すべてのフィルタークラスを削除する場合は、disablePlugins
メカニズムを使用して無効にすることができます。
lazy val root = project.in(file(".")).enablePlugins(PlayScala).disablePlugins(PlayFilters)
GuiceApplicationBuilder
を含む機能テストを作成している場合は、configure
を呼び出すことでテストですべてのフィルターを無効にすることができます。
class UserControllerWithoutFiltersSpec extends Specification {
"UserControllerWithoutFiltersSpec GET" should {
"render the index page from the application" in new WithApplication(
GuiceApplicationBuilder().configure("play.http.filters" -> "play.api.http.NoHttpFilters").build()
) {
override def running() = {
val controller = app.injector.instanceOf[UserController]
val request = FakeRequest().withCSRFToken
val result = controller.userGet().apply(request)
status(result) must beEqualTo(OK)
contentType(result) must beSome("text/html")
}
}
}
}
§コンパイル時デフォルトフィルター
コンパイル時依存性注入を使用している場合、デフォルトフィルターは実行時ではなく、コンパイル時に解決されます。
つまり、play.api.BuiltInComponents
トレイト(Scala用)とplay.BuiltInComponents
インターフェース(Java用)には、抽象のまま残されているhttpFilters
メソッドが含まれるようになりました。フィルターのデフォルトリストは、Scalaのplay.filters.HttpFiltersComponents
とJavaのplay.filters.components.HttpFiltersComponents
で定義されています。そのため、ほとんどの場合、HttpFiltersComponents
をミックスインして独自のフィルターを追加することをお勧めします。
- Java
-
import play.ApplicationLoader; import play.BuiltInComponentsFromContext; import play.filters.components.HttpFiltersComponents; import play.mvc.EssentialFilter; import play.routing.Router; import java.util.ArrayList; import java.util.List; public class MyAppComponents extends BuiltInComponentsFromContext implements HttpFiltersComponents { public MyAppComponents(ApplicationLoader.Context context) { super(context); } @Override public List<EssentialFilter> httpFilters() { List<EssentialFilter> combinedFilters = new ArrayList<>(HttpFiltersComponents.super.httpFilters()); combinedFilters.add(new LoggingFilter(materializer())); return combinedFilters; } @Override public Router router() { return Router.empty(); // implement the router as needed } }
- Scala
-
import org.apache.pekko.util.ByteString import play.api.libs.streams.Accumulator import play.api.mvc.EssentialAction import play.api.mvc.EssentialFilter import play.api.mvc.RequestHeader import play.api.mvc.Result import play.api.routing.Router import play.api.ApplicationLoader import play.api.BuiltInComponentsFromContext import play.api.NoHttpFiltersComponents import play.filters.csrf.CSRFFilter class MyAppComponents(context: ApplicationLoader.Context) extends BuiltInComponentsFromContext(context) with play.filters.HttpFiltersComponents { lazy val loggingFilter = new LoggingFilter() override def httpFilters: Seq[EssentialFilter] = { super.httpFilters :+ loggingFilter } override def router: Router = Router.empty // implement the router as needed }
リストから要素をフィルターアウトする場合は、次の手順を実行します。
- Java
-
public class MyAppComponents extends BuiltInComponentsFromContext implements HttpFiltersComponents { public MyAppComponents(ApplicationLoader.Context context) { super(context); } @Override public List<EssentialFilter> httpFilters() { return HttpFiltersComponents.super.httpFilters().stream() .filter(filter -> !filter.getClass().equals(CSRFFilter.class)) .collect(Collectors.toList()); } @Override public Router router() { return Router.empty(); // implement the router as needed } }
- Scala
-
class MyAppComponents(context: ApplicationLoader.Context) extends BuiltInComponentsFromContext(context) with play.filters.HttpFiltersComponents { override def httpFilters: Seq[EssentialFilter] = { super.httpFilters.filterNot(_.getClass == classOf[CSRFFilter]) } override def router: Router = Router.empty // implement the router as needed }
§コンパイル時デフォルトフィルターの無効化
デフォルトフィルターを無効にするには、Scalaのplay.api.NoHttpFiltersComponents
とJavaのplay.filters.components.NoHttpFiltersComponents
をミックスインします。
- Java
-
public class MyAppComponents extends BuiltInComponentsFromContext implements NoHttpFiltersComponents { public MyAppComponents(ApplicationLoader.Context context) { super(context); } // no need to override httpFilters method @Override public Router router() { return Router.empty(); // implement the router as needed } }
- Scala
-
class MyAppComponents(context: ApplicationLoader.Context) extends BuiltInComponentsFromContext(context) with NoHttpFiltersComponents { override def router: Router = Router.empty // implement the router as needed }
Scalaのplay.api.NoHttpFiltersComponents
とplay.filters.components.NoHttpFiltersComponents
の両方には、フィルターの空のリストを返すhttpFilters
メソッドがあります。
次へ: gzipエンコードの設定
このドキュメントにエラーを見つけましたか?このページのソースコードはこちらにあります。ドキュメントガイドラインを読んだ後、プルリクエストを自由に投稿してください。ご質問やアドバイスがありましたら、コミュニティフォーラムにアクセスして、コミュニティとの会話を開始してください。