The authorise() method is used in all the examples. It does the Basic HTTP Authorisation, setting response headers and throwing a HttpStatus to communicate to the browser.

authorise() does the following:

First it checks if an Authorization header was sent and if not we challenge the request by returning a HTTP status code of 401 Unauthorized.

The Authorization header should look like this:

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

If it doesn't exist we set the following HTTP response header:

WWW-Authenticate: Basic realm="What's the magic word?"

The realm attribute is the message displayed in the browser's dialogue box. It usually describes the domain that's being protect, such as "Alien-Factory Admin". Browsers often cache credentials against the domain, so you don't have to re-type them for each page.

Next we check the type of Authorization. If it is not Basic then we reject it as a Bad Request.

The gobbledygook that follows is the username and password, combined with a : and then Base64 encoded. So we decode the credentials and do a basic String comparison. Here we check for a username of admin and a password of 1234.

If no errors were thrown then protectFile() simply returns the secret file!

Protect a Directory

A more common usage is to protect all URLs under a directory, such as /admin. First we'll configure BedSheet to serve up the secret documents:

...with Middleware

Http requests are passed through a stack of Middleware classes until one of them handles it, that is, returns true or throws an Err. The AssetsMiddleware is responsible for returning files (as configured by FileHandler), so we want to make sure our authorisation Middleware is processed before it.

If the request URI starts with /admin/ then we authorise(). If it passed (no Errs) then we let processing continue down the pipeline.

...with a Middleware Service

With a bit more effort we can take the example further and convert our BasicHttpAuth middleware class into an IoC service. We can even protect multiple directory URLs by making the service configurable, and contributing to it from our own AppModule!

If you were to build an authentication library then this is the preferred design pattern.

We'll start by converting BasicHttpAuth into an IoC service. Do this by simply declaring it in the AppModule bind method:

Void bind(RegistryBuilder bob){
bob.addService(BasicHttpAuth#)}

When we configure MiddlewarePipeline be sure to contribute the actual BasicHttpAuth service instance and not some autobuilt class. Do this by declaring it as a method parameter, IoC will then inject the real service when it calls the method:

The changes to BasicHttpAuth are slight. We pass a list of protected URLs into the ctor, saving them to a field. When service() is called we do a simple loop to check if the request URL is protected, and call authorise() as usual: