Play HMAC
Some useful AuthActions
for working with machine/user auth based of HMAC for the robots and cookies for the monkeys.
Quick Rundown
We use HMAC-SHA-256
How to use
Assuming that you are using pan-domain-auth-play
and have already set up pan-domain-auth
(see the instructions on those repos for details on how to do this), then it should be as simple as:
build.sbt
libraryDependencies += "com.gu" %% "panda-hmac-play_2.6" % "1.3.1"
controller
import com.gu.pandahmac.HMACAuthActions
.
.
.
@Singleton
class MyController @Inject()(override val config:Configuration,
override val controllerComponents:ControllerComponents,
override val wsClient:WSClient,
override val refresher:InjectableRefresher)
extends AbstractController(controllerComponents) with PanDomainAuthActions with HMACAuthActions {
override def secret = "mysecret" //or more likely, config.get[String]("application.hmacSecret")
def myApiActionWithBody = APIHMACAuthAction.async(circe.json(2048)) { request=>
.
.
.
}
def myRegularAction = HMACAuthAction {
}
def myRegularAsyncAction = HMACAuthAction.async {
}
How to setup a machine client
There are example clients for Scala, Javascript and Python in the examples/
directory.
Each client needs a copy of the shared secret, defined as "mysecret" in the controller example above. Each request needs a standard (RFC-7231) HTTP Date header, and an authorization digest that is calculated like this:
- Make a "string to sign" consisting of the HTTP Date and the Path part of the URI you're trying to access, seperated by a literal newline (unix-style, not CRLF)
- Calculate the HMAC digest of the "string to sign" using the shared secret as a key and the HMAC-SHA-256 algorithm
- Base64 encode the binary output of the HMAC digest to get a random-looking string
- Add the HTTP date to the request headers with the header name 'X-Gu-Tools-HMAC-Date'
- Add another header called 'X-Gu-Tools-HMAC-Token' and set its value to the literal string HMAC followed by a space and the digest, like this:
X-Gu-Tools-HMAC-Token: HMAC boXSTNumKWRX3eQk/BBeHYk
- Send the request and the server should respond with a success.
- The default allowable clock skew is 5 minutes, if you have problems then this is the first thing to check.