diff --git a/lib/Hikaru/Action.hs b/lib/Hikaru/Action.hs
index 9bb657e3159a763d7cdb9320e156dfd488d93f57..fb283541f26bb5c2d6a79f508acfedc7d46d4c05 100644
--- a/lib/Hikaru/Action.hs
+++ b/lib/Hikaru/Action.hs
@@ -20,6 +20,7 @@ module Hikaru.Action
   , getHeaders
   , getHeaderMaybe
   , getHeaderDefault
+  , getBasicAuth
   , getAccept
   , getAcceptCharset
   , getAcceptEncoding
@@ -118,9 +119,11 @@ where
   import qualified Network.Wai.Parse as Parse
 
   import Control.Monad.Trans.Resource
-  import UnliftIO
   import Data.Aeson
   import Data.Binary.Builder
+  import Data.ByteArray.Encoding
+  import Data.ByteString.Char8 (words, span, drop)
+  import Data.CaseInsensitive (mk)
   import Data.Dynamic
   import Data.List (deleteBy, lookup, map, filter)
   import Hikaru.Media
@@ -132,6 +135,7 @@ where
   import Network.Wai
   import Network.Wai.Handler.WebSockets
   import System.IO.Unsafe
+  import UnliftIO
   import Web.Cookie
 
   import qualified Network.WebSockets as WS
@@ -227,11 +231,11 @@ where
     bracket_ (return ()) (finalize env) do
       _   <- run env
 
-      st  <- readIORef $ aeRespStatus  $ env
-      hs  <- readIORef $ aeRespHeaders $ env
-      mk  <- readIORef $ aeRespMaker   $ env
+      status  <- readIORef $ aeRespStatus  $ env
+      headers <- readIORef $ aeRespHeaders $ env
+      make    <- readIORef $ aeRespMaker   $ env
 
-      resp (mk st hs)
+      resp (make status headers)
 
     where
       finalize :: ActionEnv -> IO ()
@@ -329,6 +333,14 @@ where
   getHeaderDefault n v = fromMaybe v <$> getHeaderMaybe n
 
 
+  -- |
+  -- Obtain the login and password pair from the Authorization
+  -- request header, if present.
+  --
+  getBasicAuth :: (MonadAction m) => m (Maybe (Text, Text))
+  getBasicAuth = (parseBasicAuth =<<) <$> getHeaderMaybe "Authorization"
+
+
   -- |
   -- Obtain the Accept header value or the default value of @\"*/*\"@.
   --
@@ -1262,4 +1274,20 @@ where
   cs2 (x, y) = (cs x, cs y)
 
 
+  decodeBase64 :: ByteString -> Either String ByteString
+  decodeBase64 bstr = convertFromBase Base64 bstr
+
+
+  parseBasicAuth :: ByteString -> Maybe (Text, Text)
+  parseBasicAuth value =
+    case words value of
+      [method, auth] | mk method == "Basic" -> do
+        case decodeBase64 auth of
+          Left _   -> Nothing
+          Right lp -> let (l, p) = span (/= ':') lp
+                       in Just (cs l, cs (drop 1 p))
+
+      _otherwise -> Nothing
+
+
 -- vim:set ft=haskell sw=2 ts=2 et: