Skip to content
This repository was archived by the owner on Apr 24, 2024. It is now read-only.

Commit 9c9b976

Browse files
committed
! routing: AuthenticationFailedRejection now directly contains challenge headers to return, fixes #538
This has two consequences: * it's easier to implement a custom authenticators which can now supply the challenge headers directly instead of needing a detour through HttpAuthenticator.getChallengeHeaders * AuthenticationFailedRejection is now serializable
1 parent b05dc16 commit 9c9b976

File tree

4 files changed

+7
-6
lines changed

4 files changed

+7
-6
lines changed

spray-routing-tests/src/test/scala/spray/routing/SecurityDirectivesSpec.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import AuthenticationFailedRejection._
2626
class SecurityDirectivesSpec extends RoutingSpec {
2727

2828
val dontAuth = BasicAuth(UserPassAuthenticator[BasicUserContext](_ Future.successful(None)), "Realm")
29+
val challenge = `WWW-Authenticate`(HttpChallenge("basic", "Realm"))
2930

3031
val doAuth = BasicAuth(UserPassAuthenticator[BasicUserContext] { userPassOption
3132
Future.successful(Some(BasicUserContext(userPassOption.get.user)))
@@ -35,12 +36,12 @@ class SecurityDirectivesSpec extends RoutingSpec {
3536
"reject requests without Authorization header with an AuthenticationFailedRejection" in {
3637
Get() ~> {
3738
authenticate(dontAuth) { echoComplete }
38-
} ~> check { rejection === AuthenticationFailedRejection(CredentialsMissing, dontAuth) }
39+
} ~> check { rejection === AuthenticationFailedRejection(CredentialsMissing, List(challenge)) }
3940
}
4041
"reject unauthenticated requests with Authorization header with an AuthenticationFailedRejection" in {
4142
Get() ~> Authorization(BasicHttpCredentials("Bob", "")) ~> {
4243
authenticate(dontAuth) { echoComplete }
43-
} ~> check { rejection === AuthenticationFailedRejection(CredentialsRejected, dontAuth) }
44+
} ~> check { rejection === AuthenticationFailedRejection(CredentialsRejected, List(challenge)) }
4445
}
4546
"reject requests with illegal Authorization header with 401" in {
4647
Get() ~> RawHeader("Authorization", "bob alice") ~> handleRejections(RejectionHandler.Default) {

spray-routing/src/main/scala/spray/routing/Rejection.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ case class UnacceptedResponseEncodingRejection(supported: HttpEncoding) extends
127127
* specified in the cause.
128128
*/
129129
case class AuthenticationFailedRejection(cause: AuthenticationFailedRejection.Cause,
130-
authenticator: HttpAuthenticator[_]) extends Rejection
130+
challengeHeaders: List[HttpHeader]) extends Rejection
131131

132132
object AuthenticationFailedRejection {
133133
/**

spray-routing/src/main/scala/spray/routing/RejectionHandler.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ object RejectionHandler {
3636
implicit val Default = apply {
3737
case Nil complete(NotFound, "The requested resource could not be found.")
3838

39-
case AuthenticationFailedRejection(cause, authenticator) :: _
39+
case AuthenticationFailedRejection(cause, challengeHeaders) :: _
4040
val rejectionMessage = cause match {
4141
case CredentialsMissing "The resource requires authentication, which was not supplied with the request"
4242
case CredentialsRejected "The supplied authentication is invalid"
4343
}
44-
ctx ctx.complete(Unauthorized, authenticator.getChallengeHeaders(ctx.request), rejectionMessage)
44+
ctx ctx.complete(Unauthorized, challengeHeaders, rejectionMessage)
4545

4646
case AuthorizationFailedRejection :: _
4747
complete(Forbidden, "The supplied authentication is not authorized to access this resource")

spray-routing/src/main/scala/spray/routing/authentication/HttpAuthenticator.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ trait HttpAuthenticator[U] extends ContextAuthenticator[U] {
3737
case Some(userContext) Right(userContext)
3838
case None
3939
val cause = if (authHeader.isEmpty) CredentialsMissing else CredentialsRejected
40-
Left(AuthenticationFailedRejection(cause, this))
40+
Left(AuthenticationFailedRejection(cause, getChallengeHeaders(ctx.request)))
4141
}
4242
}
4343

0 commit comments

Comments
 (0)