Merge pull request #20010 from ktoso/wip-authorizeAsync-ktoso
+htp #20002 add authorizeAsync
This commit is contained in:
commit
f679c9f0b1
8 changed files with 140 additions and 4 deletions
|
|
@ -219,7 +219,7 @@ class SecurityDirectivesExamplesSpec extends RoutingSpec {
|
|||
}
|
||||
}
|
||||
|
||||
"0authorize" in {
|
||||
"0authorize-0" in {
|
||||
case class User(name: String)
|
||||
|
||||
// authenticate the user:
|
||||
|
|
@ -260,6 +260,48 @@ class SecurityDirectivesExamplesSpec extends RoutingSpec {
|
|||
}
|
||||
}
|
||||
|
||||
"0authorizeAsync" in {
|
||||
case class User(name: String)
|
||||
|
||||
// authenticate the user:
|
||||
def myUserPassAuthenticator(credentials: Credentials): Option[User] =
|
||||
credentials match {
|
||||
case Credentials.Provided(id) => Some(User(id))
|
||||
case _ => None
|
||||
}
|
||||
|
||||
// check if user is authorized to perform admin actions,
|
||||
// this could potentially be a long operation so it would return a Future
|
||||
val admins = Set("Peter")
|
||||
def hasAdminPermissions(user: User): Future[Boolean] =
|
||||
Future.successful(admins.contains(user.name))
|
||||
|
||||
val route =
|
||||
Route.seal {
|
||||
authenticateBasic(realm = "secure site", myUserPassAuthenticator) { user =>
|
||||
path("peters-lair") {
|
||||
authorizeAsync(_ => hasAdminPermissions(user)) {
|
||||
complete(s"'${user.name}' visited Peter's lair")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tests:
|
||||
val johnsCred = BasicHttpCredentials("John", "p4ssw0rd")
|
||||
Get("/peters-lair") ~> addCredentials(johnsCred) ~> // adds Authorization header
|
||||
route ~> check {
|
||||
status shouldEqual StatusCodes.Forbidden
|
||||
responseAs[String] shouldEqual "The supplied authentication is not authorized to access this resource"
|
||||
}
|
||||
|
||||
val petersCred = BasicHttpCredentials("Peter", "pan")
|
||||
Get("/peters-lair") ~> addCredentials(petersCred) ~> // adds Authorization header
|
||||
route ~> check {
|
||||
responseAs[String] shouldEqual "'Peter' visited Peter's lair"
|
||||
}
|
||||
}
|
||||
|
||||
"0extractCredentials" in {
|
||||
val route =
|
||||
extractCredentials { creds =>
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ Directive Description
|
|||
a given ``AsyncAuthenticatorPF[T]``
|
||||
:ref:`-authenticateOrRejectWithChallenge-` Lifts an authenticator function into a directive
|
||||
:ref:`-authorize-` Applies the given authorization check to the request
|
||||
:ref:`-authorizeAsync-` Applies the given asynchronous authorization check to the request
|
||||
:ref:`-cancelRejection-` Adds a ``TransformationRejection`` cancelling all rejections equal to the
|
||||
given one to the rejections potentially coming back from the inner route.
|
||||
:ref:`-cancelRejections-` Adds a ``TransformationRejection`` cancelling all matching rejections
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ If the check returns ``true`` the request is passed on to the inner route unchan
|
|||
In a common use-case you would check if a user (e.g. supplied by any of the ``authenticate*`` family of directives,
|
||||
e.g. :ref:`-authenticateBasic-`) is allowed to access the inner routes, e.g. by checking if the user has the needed permissions.
|
||||
|
||||
See also :ref:`-authorize-` for the asynchronous version of this directive.
|
||||
|
||||
.. note::
|
||||
See also :ref:`authentication-vs-authorization-scala` to understand the differences between those.
|
||||
|
|
@ -32,4 +33,4 @@ Example
|
|||
-------
|
||||
|
||||
.. includecode2:: ../../../../code/docs/http/scaladsl/server/directives/SecurityDirectivesExamplesSpec.scala
|
||||
:snippet: 0authorize
|
||||
:snippet: 0authorize-0
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
.. _-authorizeAsync-:
|
||||
|
||||
authorizeAsync
|
||||
==============
|
||||
|
||||
Signature
|
||||
---------
|
||||
|
||||
.. includecode2:: /../../akka-http/src/main/scala/akka/http/scaladsl/server/directives/SecurityDirectives.scala
|
||||
:snippet: authorizeAsync
|
||||
|
||||
Description
|
||||
-----------
|
||||
Applies the given authorization check to the request.
|
||||
|
||||
The user-defined authorization check can either be supplied as a ``=> Future[Boolean]`` value which is calculated
|
||||
just from information out of the lexical scope, or as a function ``RequestContext => Future[Boolean]`` which can also
|
||||
take information from the request itself into account.
|
||||
|
||||
If the check returns ``true`` or the ``Future`` is failed the request is passed on to the inner route unchanged,
|
||||
otherwise an ``AuthorizationFailedRejection`` is created, triggering a ``403 Forbidden`` response by default
|
||||
(the same as in the case of an ``AuthenticationFailedRejection``).
|
||||
|
||||
In a common use-case you would check if a user (e.g. supplied by any of the ``authenticate*`` family of directives,
|
||||
e.g. :ref:`-authenticateBasic-`) is allowed to access the inner routes, e.g. by checking if the user has the needed permissions.
|
||||
|
||||
See also :ref:`-authorize-` for the synchronous version of this directive.
|
||||
|
||||
.. note::
|
||||
See also :ref:`authentication-vs-authorization-scala` to understand the differences between those.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. includecode2:: ../../../../code/docs/http/scaladsl/server/directives/SecurityDirectivesExamplesSpec.scala
|
||||
:snippet: 0authorizeAsync
|
||||
|
|
@ -17,6 +17,7 @@ SecurityDirectives
|
|||
authenticateOAuth2PFAsync
|
||||
authenticateOrRejectWithChallenge
|
||||
authorize
|
||||
authorizeAsync
|
||||
extractCredentials
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue