the Credentials Object used in the authenticateBasic Directive can be verified against passwords that are stored with a hashing function. By providing the same hashing function as an argument the clear-text password in the HttpCredentials will be hashed the same way prior to comparing against the stored secret.
This commit is contained in:
parent
6777e7f7d9
commit
3723959b69
1 changed files with 14 additions and 3 deletions
|
|
@ -268,24 +268,35 @@ sealed trait Credentials
|
||||||
object Credentials {
|
object Credentials {
|
||||||
case object Missing extends Credentials
|
case object Missing extends Credentials
|
||||||
abstract case class Provided(identifier: String) extends Credentials {
|
abstract case class Provided(identifier: String) extends Credentials {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* First applies the passed in `hasher` function to the received secret part of the Credentials
|
||||||
|
* and then safely compares the passed in `secret` with the hashed received secret.
|
||||||
|
* This method can be used if the secret is not stored in plain text.
|
||||||
|
* Use of this method instead of manual String equality testing is recommended in order to guard against timing attacks.
|
||||||
|
*
|
||||||
|
* See also [[EnhancedString#secure_==]], for more information.
|
||||||
|
*/
|
||||||
|
def verify(secret: String, hasher: String ⇒ String): Boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Safely compares the passed in `secret` with the received secret part of the Credentials.
|
* Safely compares the passed in `secret` with the received secret part of the Credentials.
|
||||||
* Use of this method instead of manual String equality testing is recommended in order to guard against timing attacks.
|
* Use of this method instead of manual String equality testing is recommended in order to guard against timing attacks.
|
||||||
*
|
*
|
||||||
* See also [[EnhancedString#secure_==]], for more information.
|
* See also [[EnhancedString#secure_==]], for more information.
|
||||||
*/
|
*/
|
||||||
def verify(secret: String): Boolean
|
def verify(secret: String): Boolean = verify(secret, x => x)
|
||||||
}
|
}
|
||||||
|
|
||||||
def apply(cred: Option[HttpCredentials]): Credentials = {
|
def apply(cred: Option[HttpCredentials]): Credentials = {
|
||||||
cred match {
|
cred match {
|
||||||
case Some(BasicHttpCredentials(username, receivedSecret)) ⇒
|
case Some(BasicHttpCredentials(username, receivedSecret)) ⇒
|
||||||
new Credentials.Provided(username) {
|
new Credentials.Provided(username) {
|
||||||
def verify(secret: String): Boolean = secret secure_== receivedSecret
|
def verify(secret: String, hasher: String ⇒ String): Boolean = secret secure_== hasher(receivedSecret)
|
||||||
}
|
}
|
||||||
case Some(OAuth2BearerToken(token)) ⇒
|
case Some(OAuth2BearerToken(token)) ⇒
|
||||||
new Credentials.Provided(token) {
|
new Credentials.Provided(token) {
|
||||||
def verify(secret: String): Boolean = secret secure_== token
|
def verify(secret: String, hasher: String ⇒ String): Boolean = secret secure_== hasher(token)
|
||||||
}
|
}
|
||||||
case Some(GenericHttpCredentials(scheme, token, params)) ⇒
|
case Some(GenericHttpCredentials(scheme, token, params)) ⇒
|
||||||
throw new UnsupportedOperationException("cannot verify generic HTTP credentials")
|
throw new UnsupportedOperationException("cannot verify generic HTTP credentials")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue