2015-12-23 23 views
7

Yürütme 2.3'te, farklı filtrelere göre farklı istek yollarını veya yöntemlerini devre dışı bırakabilirim. Ancak, Play 2.4'te bunu yapmanın bir yolunu bulamıyorum. https://www.playframework.com/documentation/2.4.x/ScalaHttpFilters. Play 2.4 HttpFilters uygulamasında nasıl benzer sonuçlara ulaşabilirim?Oynat 2.4 İstek yoluna ya da yöntemine göre ayarlanmış belirli filtreleri devre dışı bırakma

Oyun 2.3'te bunu nasıl yaptım. Play HttpFilters mevcut hiçbir RequestHeader yoktur

object CacheCtrlHeadersFilter extends EssentialFilter { 
    def apply(action: EssentialAction) = new EssentialAction { 
    def apply(requestHeader: RequestHeader) = { 
     action(requestHeader).map { result => 
     result.withHeaders(
      CACHE_CONTROL -> "no-cache, no-store, must-revalidate, private", 
      PRAGMA -> "no-cache" 
     ) 
     } 
    } 
    } 
} 

import play.api.libs.iteratee._ 
object FilterChainByRequestHeader { 
    def apply[A](action: EssentialAction, filtersFun: (RequestHeader) => List[EssentialFilter]): EssentialAction = new EssentialAction { 
    def apply(rh: RequestHeader): Iteratee[Array[Byte], Result] = { 
     val chain = filtersFun(rh).reverse.foldLeft(action) { (a, i) => i(a) } 
     chain(rh) 
    } 
    } 
} 

object Global extends GlobalSettings { 

    val securityFilter = SecurityHeadersFilter() 
    val defaultFilters = List(securityFilter, 
          CacheCtrlHeadersFilter) 

    def filters(rh: RequestHeader) = { 
    if (rh.method == "OPTIONS")      <----------- by method 
     defaultFilters.filterNot(_.eq(securityFilter)) 
    else if (rh.path.startsWith("/apps/google"))  <----------- by path 
     defaultFilters.filterNot(_.eq(securityFilter)) 
    else defaultFilters 
    } 
    override def doFilter(a: EssentialAction): EssentialAction = { 
    FilterChainByRequestHeader(super.doFilter(a), filters) 
    } 

} 

2,4

class Filters @Inject() (
    securityHeadersFilter: SecurityHeadersFilter, 
    cacheCtrlHeadersFilter: CacheCtrlHeadersFilter 
) extends HttpFilters { 

    val filters = Seq(securityHeadersFilter, cacheCtrlHeadersFilter) 
} 
+1

Sadece bir düşünce, ama belki de filtreyi genişletebilir ve mantığı orada kurabilirsiniz? – gpgekko

+1

@gpgekko Evet, bunu düşündüm. Ama acaba bu tek çözüm mü? – angelokh

+1

@gpgekko Ayrıca, bir filtre oluşturursam, geçerli filtreyi uygulama işlevinin içinden nasıl atlayabilirim? – angelokh

cevap

2

Yaptığım şey budur.

class SecurityHeadersFilter extends EssentialFilter { 
    def apply(action: EssentialAction) = new EssentialAction { 
    def apply(rh: RequestHeader) = { 
     action(rh).map { result => 
     if (rh.method != "OPTIONS" && !rh.path.startsWith("/apps/google")) 
      result.withHeaders(
       "X-Frame-Options" -> "SAMEORIGIN", 
       "Content-Security-Policy" -> "default-src * 'self' 'unsafe-inline' 'unsafe-eval' " 
      ) 
     } 
    } 
    } 
} 

class Filters @Inject() (
    gzip: GzipFilter, 
    cache: CacheCtrlHeadersFilter, 
    cors: CorsFilter, 
    security: SecurityHeadersFilter 
) extends HttpFilters { 
    val filters = Seq(gzip, cache, cors, security) 
} 
3
object Global extends WithFilters(new CoreActionFilter()) { 

} 


class CoreActionFilter extends Filter { 

    lazy val serviceLogger = Logger("services") 

    def apply(nextFilter: RequestHeader => Future[Result])(requestHeader: RequestHeader) = { 

    nextFilter(requestHeader).map { result => 

     val action = requestHeader.path match { 
     case "/favicon.ico" => s"[ ${requestHeader.remoteAddress.toString}]" 
     case _ => s"[ ${requestHeader.remoteAddress.toString}]" + ("[") + requestHeader.tags(Tags.RoutePattern) + ("]") + ("[") + requestHeader.tags(Tags.RouteController) + "." + requestHeader.tags(Tags.RouteActionMethod) + ("]") 
     } 

     val startTime = System.currentTimeMillis 
     val endTime = System.currentTimeMillis 
     val requestTime = endTime - startTime 
     val token = requestHeader.headers.get("X-Auth-Token") 
     serviceLogger.info(s"[$token]" + s"${action}[${requestTime}ms]" + s"[${result.header.status}]") 
     result.withHeaders("Request-Time" -> requestTime.toString) 

    }(CoreContexts.simpleSqlQuery) 

    } 
} 
+1

Cevabınızı açıklayabilir misiniz? Sağladığınız yöntemde bir filtreyi nasıl atlayabilirim? – angelokh

+1

Lütfen uygulamamı gör: Projemde ayrıca bir filtreleri var. Filtremde koşul doğrulamasını koydum. Örneğin: CoreActionFilter. Durum doğrulamasını yapmak için başvuru yöntemini uygulayabilirsiniz. – Birdflying1005

2

My uygulaması:

sınıf Filtreler @ Enjekte() (corsFilter: CORSFilter, coreActionFilter: CoreActionFilter), HttpFilters { def filtrelerini = Seq (corsFilter, coreActionFilter)genişletir}

sınıf CoreActionFilter uzanan filtre { def uygulanır (nextFilter: RequestHeader => Gelecek [Sonuç]) (requestHeader: RequestHeader) = {

if(/*yourContidion*/) { 

    nextFilter(requestHeader).map { result => 

    val action = requestHeader.path match { 
     case "/favicon.ico" => s"[ ${requestHeader.remoteAddress.toString}]" 
     case _ => s"[ ${requestHeader.remoteAddress.toString}]" + ("[") + requestHeader.tags(Tags.RoutePattern) + ("]") + ("[") + requestHeader.tags(Tags.RouteController) + "." + requestHeader.tags(Tags.RouteActionMethod) + ("]") 
    } 

    val startTime = System.currentTimeMillis 
    val endTime = System.currentTimeMillis 
    val requestTime = endTime - startTime 
    val token = requestHeader.headers.get("X-Auth-Token") 
    serviceLogger.info(s"[$token]" + s"${action}[${requestTime}ms]" + s"[${result.header.status}]") 
    result.withHeaders("Request-Time" -> requestTime.toString) 

    }(CoreContexts.simpleSqlQuery) 
} 
nextFilter(requestHeader) 

} }

+0

Lütfen yeni bir cevap göndermek yerine, bir şeyler eklemek istediğinizde önceki cevabınızı düzenleyin – gpgekko

1

Bu, nasıl uygulamıştır. Çalışıyor, ama ideal değil. Temel olarak, isteği zenginleştirmek için bir dış WhiteListFilter ekliyoruz, böylece istek asla filtrelenmeyecek. Filtre, yanıtı manipüle etmekle ilgili ise, o zaman aynı filtre unset cevabını etkin bir şekilde kullanabilir.

Yasal Uyarı, Sadece resim almak için aşağıdaki kodu bir metin düzenleyicisiyle yazdım. Derleme garantisi verilemez:

object WhiteListFilter extends EssentialFilter { 

    override def apply(next: EssentialAction) = new EssentialAction { 
    override def apply(req: RequestHeader) = { 

     val whiteListedReq = 
     // if the filter is about to block some request by headers 
     // then append the valid headers, to `whitelist` request 
     if (req.method == "OPTIONS") { 
      req.copy(headers = req.headers.add("XXX" -> "XXX")) 
     } else { 
      req 
     } 

     next(whiteListedReq).map { 
     resp => 
      // if the filter is about to manipulate response 
      // then unset the actions 
      if (req.method == "OPTIONS") { 
      val headers = resp.headers - "key1" - "key2" 
      resp.copy(headers = headers) 
      } else { 
      resp 
      } 
     } 
    } 
    } 
}