Simple Webmachine Extension (2/4): Authorization

This is the second post in a four-part series about extending a simple Webmachine resource. The first part discussed adding support for the HTTP method PUT.

Authorization

Something about modification of server state screams, "Password protection!" at me. Let's guard the PUT method with Basic auth:

-export([is_authorized/2]).

-define(AUTH_HEAD, "Basic realm=MyOSEnv").

is_authorized(RD, Ctx) ->
    case wrq:method(RD) of
        'PUT' -> basic_auth(RD, Ctx);
        _     -> {true, RD, Ctx}
    end.

basic_auth(RD, Ctx) ->
    case wrq:get_req_header("Authorization", RD) of
        "Basic "++Base64 ->
            case string:tokens(base64:mime_decode_to_string(Base64), ":") of
                ["webmachine", "rules"] -> {true, RD, Ctx};
                _                       -> {?AUTH_HEAD, RD, Ctx}
            end;
        _ -> {?AUTH_HEAD, RD, Ctx}
    end.

Arbitrary decisions:

  • Only PUT is protected. If GET and HEAD should be protected as well, just replace the body of is_authorized/2 with the body of basic_auth/2

I need to update my curl command if I don't want to be told I'm unauthorized:

$ curl -u webmachine:rules -X PUT -H "Content-type: application/json" \ 
   http://localhost:8000/_env/MY_VAR -d "\"yay\""

Come back tomorrow for part three, where I add a modicum of atomicity.

Update: part three is up.

About these ads

3 comments so far

  1. pablop on

    Enjoying your posts about webmachine.

    How does webmachine knows about is_authorized?
    Does it check if it exists and exported and use it otherwise assume no auth is required?

    Is it possible to authenticate users against credentials stored in a db and keep a session cookie?
    Can I keep the actual auth code in one place and only call it from all the resources if required? Where is the right place to put such auth backend?

    Thanks

  2. Justin Sheehy on

    Pablo,

    The is_authorized function is one of the many Webmachine Resource Functions, all documented at http://bitbucket.org/justin/webmachine/wiki/WebmachineResources

    The table on that page shows the default values for each of those functions which will be used if your resource function does not export it.

    It is definitely possible (and not very hard) to do all of the things you ask, including checking auth with a database, using a single central auth function, and so on. However, Webmachine is a Web toolkit and not a framework — it makes no claims to know better than you what the “right” way is to make such application-specific decisions.

  3. Bryan on

    Hey, Pablo. Just to echo Justin – yes, webmachine checks to see if you’ve defined is_authorized/2, and uses a default if you haven’t.

    In the implementation of is_authorized, it’s absolutely possible to query some authorization repository, or any other completely arbitrary set of parameters (file existence, time of day, random bit stream, …). It’s a function – compute what you want. :)

    And yes, if it makes sense for your app, it’s a great idea to put your auth code in a module that can be called from the is_authorized of many different resources. Reuse through modularity for the win!


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: