This commit is contained in:
parent
95280bf16f
commit
f33f2197b6
7 changed files with 54 additions and 22 deletions
|
|
@ -34,7 +34,7 @@ class SecurityDirectivesExamplesSpec extends RoutingSpec {
|
|||
Get("/secured") ~> route ~> check {
|
||||
status shouldEqual StatusCodes.Unauthorized
|
||||
responseAs[String] shouldEqual "The resource requires authentication, which was not supplied with the request"
|
||||
header[`WWW-Authenticate`].get.challenges.head shouldEqual HttpChallenge("Basic", "secure site")
|
||||
header[`WWW-Authenticate`].get.challenges.head shouldEqual HttpChallenge("Basic", Some("secure site"))
|
||||
}
|
||||
|
||||
val validCredentials = BasicHttpCredentials("John", "p4ssw0rd")
|
||||
|
|
@ -49,7 +49,7 @@ class SecurityDirectivesExamplesSpec extends RoutingSpec {
|
|||
route ~> check {
|
||||
status shouldEqual StatusCodes.Unauthorized
|
||||
responseAs[String] shouldEqual "The supplied authentication is invalid"
|
||||
header[`WWW-Authenticate`].get.challenges.head shouldEqual HttpChallenge("Basic", "secure site")
|
||||
header[`WWW-Authenticate`].get.challenges.head shouldEqual HttpChallenge("Basic", Some("secure site"))
|
||||
}
|
||||
}
|
||||
"authenticateBasicPF-0" in {
|
||||
|
|
@ -71,7 +71,7 @@ class SecurityDirectivesExamplesSpec extends RoutingSpec {
|
|||
Get("/secured") ~> route ~> check {
|
||||
status shouldEqual StatusCodes.Unauthorized
|
||||
responseAs[String] shouldEqual "The resource requires authentication, which was not supplied with the request"
|
||||
header[`WWW-Authenticate`].get.challenges.head shouldEqual HttpChallenge("Basic", "secure site")
|
||||
header[`WWW-Authenticate`].get.challenges.head shouldEqual HttpChallenge("Basic", Some("secure site"))
|
||||
}
|
||||
|
||||
val validCredentials = BasicHttpCredentials("John", "p4ssw0rd")
|
||||
|
|
@ -92,7 +92,7 @@ class SecurityDirectivesExamplesSpec extends RoutingSpec {
|
|||
route ~> check {
|
||||
status shouldEqual StatusCodes.Unauthorized
|
||||
responseAs[String] shouldEqual "The supplied authentication is invalid"
|
||||
header[`WWW-Authenticate`].get.challenges.head shouldEqual HttpChallenge("Basic", "secure site")
|
||||
header[`WWW-Authenticate`].get.challenges.head shouldEqual HttpChallenge("Basic", Some("secure site"))
|
||||
}
|
||||
}
|
||||
"authenticateBasicPFAsync-0" in {
|
||||
|
|
@ -120,7 +120,7 @@ class SecurityDirectivesExamplesSpec extends RoutingSpec {
|
|||
Get("/secured") ~> route ~> check {
|
||||
status shouldEqual StatusCodes.Unauthorized
|
||||
responseAs[String] shouldEqual "The resource requires authentication, which was not supplied with the request"
|
||||
header[`WWW-Authenticate`].get.challenges.head shouldEqual HttpChallenge("Basic", "secure site")
|
||||
header[`WWW-Authenticate`].get.challenges.head shouldEqual HttpChallenge("Basic", Some("secure site"))
|
||||
}
|
||||
|
||||
val validCredentials = BasicHttpCredentials("John", "p4ssw0rd")
|
||||
|
|
@ -135,7 +135,7 @@ class SecurityDirectivesExamplesSpec extends RoutingSpec {
|
|||
route ~> check {
|
||||
status shouldEqual StatusCodes.Unauthorized
|
||||
responseAs[String] shouldEqual "The supplied authentication is invalid"
|
||||
header[`WWW-Authenticate`].get.challenges.head shouldEqual HttpChallenge("Basic", "secure site")
|
||||
header[`WWW-Authenticate`].get.challenges.head shouldEqual HttpChallenge("Basic", Some("secure site"))
|
||||
}
|
||||
}
|
||||
"authenticateBasicAsync-0" in {
|
||||
|
|
@ -163,7 +163,7 @@ class SecurityDirectivesExamplesSpec extends RoutingSpec {
|
|||
Get("/secured") ~> route ~> check {
|
||||
status shouldEqual StatusCodes.Unauthorized
|
||||
responseAs[String] shouldEqual "The resource requires authentication, which was not supplied with the request"
|
||||
header[`WWW-Authenticate`].get.challenges.head shouldEqual HttpChallenge("Basic", "secure site")
|
||||
header[`WWW-Authenticate`].get.challenges.head shouldEqual HttpChallenge("Basic", Some("secure site"))
|
||||
}
|
||||
|
||||
val validCredentials = BasicHttpCredentials("John", "p4ssw0rd")
|
||||
|
|
@ -178,11 +178,11 @@ class SecurityDirectivesExamplesSpec extends RoutingSpec {
|
|||
route ~> check {
|
||||
status shouldEqual StatusCodes.Unauthorized
|
||||
responseAs[String] shouldEqual "The supplied authentication is invalid"
|
||||
header[`WWW-Authenticate`].get.challenges.head shouldEqual HttpChallenge("Basic", "secure site")
|
||||
header[`WWW-Authenticate`].get.challenges.head shouldEqual HttpChallenge("Basic", Some("secure site"))
|
||||
}
|
||||
}
|
||||
"authenticateOrRejectWithChallenge-0" in {
|
||||
val challenge = HttpChallenge("MyAuth", "MyRealm")
|
||||
val challenge = HttpChallenge("MyAuth", Some("MyRealm"))
|
||||
|
||||
// your custom authentication logic:
|
||||
def auth(creds: HttpCredentials): Boolean = true
|
||||
|
|
@ -208,7 +208,7 @@ class SecurityDirectivesExamplesSpec extends RoutingSpec {
|
|||
Get("/secured") ~> route ~> check {
|
||||
status shouldEqual StatusCodes.Unauthorized
|
||||
responseAs[String] shouldEqual "The resource requires authentication, which was not supplied with the request"
|
||||
header[`WWW-Authenticate`].get.challenges.head shouldEqual HttpChallenge("MyAuth", "MyRealm")
|
||||
header[`WWW-Authenticate`].get.challenges.head shouldEqual HttpChallenge("MyAuth", Some("MyRealm"))
|
||||
}
|
||||
|
||||
val validCredentials = BasicHttpCredentials("John", "p4ssw0rd")
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
package akka.http.javadsl.model.headers;
|
||||
|
||||
import akka.http.impl.util.Util;
|
||||
import akka.japi.Option;
|
||||
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
|
@ -14,11 +16,28 @@ public abstract class HttpChallenge {
|
|||
|
||||
public abstract Map<String, String> getParams();
|
||||
|
||||
/**
|
||||
* @deprecated Use constructor with optional realm parameter instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static HttpChallenge create(String scheme, String realm) {
|
||||
return new akka.http.scaladsl.model.headers.HttpChallenge(scheme, realm, Util.emptyMap);
|
||||
return akka.http.scaladsl.model.headers.HttpChallenge.apply(scheme, scala.Option.apply(realm), Util.emptyMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use constructor with optional realm parameter instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static HttpChallenge create(String scheme, String realm, Map<String, String> params) {
|
||||
return new akka.http.scaladsl.model.headers.HttpChallenge(scheme, realm, Util.convertMapToScala(params));
|
||||
return akka.http.scaladsl.model.headers.HttpChallenge.apply(scheme, scala.Option.apply(realm), Util.convertMapToScala(params));
|
||||
}
|
||||
|
||||
public static HttpChallenge create(String scheme, Option<String> realm) {
|
||||
return akka.http.scaladsl.model.headers.HttpChallenge.apply(scheme, realm.asScala(), Util.emptyMap);
|
||||
}
|
||||
|
||||
public static HttpChallenge create(String scheme, Option<String> realm, Map<String, String> params) {
|
||||
return akka.http.scaladsl.model.headers.HttpChallenge.apply(scheme, realm.asScala(), Util.convertMapToScala(params));
|
||||
}
|
||||
|
||||
public static HttpChallenge createBasic(String realm) {
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ private[parser] trait CommonRules { this: Parser with StringBuilding ⇒
|
|||
def challenge = rule {
|
||||
`challenge-or-credentials` ~> { (scheme, params) ⇒
|
||||
val (realms, otherParams) = params.partition(_._1 equalsIgnoreCase "realm")
|
||||
HttpChallenge(scheme, realms.headOption.map(_._2).getOrElse(""), otherParams.toMap)
|
||||
HttpChallenge(scheme, realms.headOption.map(_._2), otherParams.toMap)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ final case class HttpChallenge(scheme: String, realm: String,
|
|||
params: Map[String, String] = Map.empty) extends jm.headers.HttpChallenge with ValueRenderable {
|
||||
|
||||
def render[R <: Rendering](r: R): r.type = {
|
||||
r ~~ scheme ~~ " realm=" ~~#! realm
|
||||
r ~~ scheme
|
||||
if (realm != null) r ~~ " realm=" ~~#! realm
|
||||
if (params.nonEmpty) params.foreach { case (k, v) ⇒ r ~~ ',' ~~ k ~~ '=' ~~# v }
|
||||
r
|
||||
}
|
||||
|
|
@ -22,6 +23,16 @@ final case class HttpChallenge(scheme: String, realm: String,
|
|||
def getParams: util.Map[String, String] = params.asJava
|
||||
}
|
||||
|
||||
// FIXME: AbstractFunction3 required for bin compat. remove in Akka 3.0 and change realm in case class to option #20786
|
||||
object HttpChallenge extends scala.runtime.AbstractFunction3[String, String, Map[String, String], HttpChallenge] {
|
||||
|
||||
def apply(scheme: String, realm: Option[String]): HttpChallenge =
|
||||
HttpChallenge(scheme, realm.orNull, Map.empty[String, String])
|
||||
|
||||
def apply(scheme: String, realm: Option[String], params: Map[String, String]): HttpChallenge =
|
||||
HttpChallenge(scheme, realm.orNull, params)
|
||||
}
|
||||
|
||||
object HttpChallenges {
|
||||
|
||||
def basic(realm: String): HttpChallenge = HttpChallenge("Basic", realm)
|
||||
|
|
|
|||
|
|
@ -373,7 +373,7 @@ class HttpHeaderSpec extends FreeSpec with Matchers {
|
|||
|
||||
"Proxy-Authenticate" in {
|
||||
"Proxy-Authenticate: Basic realm=\"WallyWorld\",attr=\"val>ue\", Fancy realm=\"yeah\"" =!=
|
||||
`Proxy-Authenticate`(HttpChallenge("Basic", "WallyWorld", Map("attr" → "val>ue")), HttpChallenge("Fancy", "yeah"))
|
||||
`Proxy-Authenticate`(HttpChallenge("Basic", Some("WallyWorld"), Map("attr" → "val>ue")), HttpChallenge("Fancy", Some("yeah")))
|
||||
}
|
||||
|
||||
"Proxy-Authorization" in {
|
||||
|
|
@ -544,11 +544,13 @@ class HttpHeaderSpec extends FreeSpec with Matchers {
|
|||
}
|
||||
|
||||
"WWW-Authenticate" in {
|
||||
"WWW-Authenticate: Basic" =!=
|
||||
`WWW-Authenticate`(HttpChallenge("Basic", None))
|
||||
"WWW-Authenticate: Basic realm=\"WallyWorld\"" =!=
|
||||
`WWW-Authenticate`(HttpChallenge("Basic", "WallyWorld"))
|
||||
`WWW-Authenticate`(HttpChallenge("Basic", Some("WallyWorld")))
|
||||
"WWW-Authenticate: BaSiC rEaLm=WallyWorld" =!=
|
||||
`WWW-Authenticate`(HttpChallenge("BaSiC", "WallyWorld")).renderedTo("BaSiC realm=\"WallyWorld\"")
|
||||
"WWW-Authenticate: Basic realm=\"foo<bar\"" =!= `WWW-Authenticate`(HttpChallenge("Basic", "foo<bar"))
|
||||
"WWW-Authenticate: Basic realm=\"foo<bar\"" =!= `WWW-Authenticate`(HttpChallenge("Basic", Some("foo<bar")))
|
||||
"""WWW-Authenticate: Digest
|
||||
realm="testrealm@host.com",
|
||||
qop="auth,auth-int",
|
||||
|
|
@ -559,9 +561,9 @@ class HttpHeaderSpec extends FreeSpec with Matchers {
|
|||
"nonce" → "dcd98b7102dd2f0e8b11d0f600bfb0c093", "opaque" → "5ccc069c403ebaf9f0171e9517f40e41"))).renderedTo(
|
||||
"Digest realm=\"testrealm@host.com\",qop=\"auth,auth-int\",nonce=dcd98b7102dd2f0e8b11d0f600bfb0c093,opaque=5ccc069c403ebaf9f0171e9517f40e41")
|
||||
"WWW-Authenticate: Basic realm=\"WallyWorld\",attr=\"val>ue\", Fancy realm=\"yeah\"" =!=
|
||||
`WWW-Authenticate`(HttpChallenge("Basic", "WallyWorld", Map("attr" → "val>ue")), HttpChallenge("Fancy", "yeah"))
|
||||
`WWW-Authenticate`(HttpChallenge("Basic", Some("WallyWorld"), Map("attr" → "val>ue")), HttpChallenge("Fancy", Some("yeah")))
|
||||
"""WWW-Authenticate: Fancy realm="Secure Area",nonce=42""" =!=
|
||||
`WWW-Authenticate`(HttpChallenge("Fancy", "Secure Area", Map("nonce" → "42")))
|
||||
`WWW-Authenticate`(HttpChallenge("Fancy", Some("Secure Area"), Map("nonce" → "42")))
|
||||
}
|
||||
|
||||
"X-Forwarded-For" in {
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ class HeaderSpec extends FreeSpec with Matchers {
|
|||
`Last-Modified`(DateTime(2016, 2, 4, 9, 9, 0)),
|
||||
Link(Uri("http://example.com"), LinkParams.`title*`("example")),
|
||||
Location(Uri("http://example.com")),
|
||||
`Proxy-Authenticate`(HttpChallenge("Basic", "example.com")),
|
||||
`Proxy-Authenticate`(HttpChallenge("Basic", Some("example.com"))),
|
||||
`Sec-WebSocket-Accept`("dGhlIHNhbXBsZSBub25jZQ"),
|
||||
`Sec-WebSocket-Extensions`(Vector(WebSocketExtension("foo"))),
|
||||
`Sec-WebSocket-Version`(Vector(13)),
|
||||
|
|
@ -161,7 +161,7 @@ class HeaderSpec extends FreeSpec with Matchers {
|
|||
`Set-Cookie`(HttpCookie("sessionId", "b0eb8b8b3ad246")),
|
||||
`Transfer-Encoding`(TransferEncodings.chunked),
|
||||
Upgrade(Vector(UpgradeProtocol("HTTP", Some("2.0")))),
|
||||
`WWW-Authenticate`(HttpChallenge("Basic", "example.com")))
|
||||
`WWW-Authenticate`(HttpChallenge("Basic", Some("example.com"))))
|
||||
|
||||
responseHeaders.foreach { header ⇒
|
||||
header shouldBe 'renderInResponses
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ class SecurityDirectivesSpec extends RoutingSpec {
|
|||
}
|
||||
"authentication directives" should {
|
||||
"properly stack" in {
|
||||
val otherChallenge = HttpChallenge("MyAuth", "MyRealm2")
|
||||
val otherChallenge = HttpChallenge("MyAuth", Some("MyRealm2"))
|
||||
val otherAuth: Directive1[String] = authenticateOrRejectWithChallenge { (cred: Option[HttpCredentials]) ⇒
|
||||
Future.successful(Left(otherChallenge))
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue