diff --git a/src/HAB/Pica/Auth/LBSAuthentication.php b/src/HAB/Pica/Auth/LBSAuthentication.php
new file mode 100644
index 0000000000000000000000000000000000000000..6c76e5529cd47f6031918f0bbe72533f4a41631c
--- /dev/null
+++ b/src/HAB/Pica/Auth/LBSAuthentication.php
@@ -0,0 +1,137 @@
+<?php
+
+/**
+ * This file is part of PicaAuth.
+ *
+ * PicaAuth is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PicaAuth is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with PicaAuth.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author    David Maus <maus@hab.de>
+ * @copyright (c) 2015 by Herzog August Bibliothek Wolfenbüttel
+ * @license   http://www.gnu.org/licenses/gpl.txt GNU General Public License v3 or higher
+ */
+
+namespace HAB\Pica\Auth;
+
+use RuntimeException;
+
+use GuzzleHttp\Client;
+use GuzzleHttp\Exception\RequestException;
+
+/**
+ * Authenticate user against the LBS4 Authentication webservice.
+ *
+ * @author    David Maus <maus@hab.de>
+ * @copyright (c) 2015 by Herzog August Bibliothek Wolfenbüttel
+ * @license   http://www.gnu.org/licenses/gpl.txt GNU General Public License v3 or higher
+ */
+class LBSAuthentication implements AuthenticationInterface
+{
+    /**
+     * Service URL.
+     *
+     * @var string
+     */
+    private $serviceUrl;
+
+    /**
+     * Catalog number.
+     *
+     * @var integer
+     */
+    private $catalogNumber;
+
+    /**
+     * User number for connecting to LBS4.
+     *
+     * @var integer
+     */
+    private $lbsUserNumber;
+
+    /**
+     * HTTP client.
+     *
+     * @var Client
+     */
+    private $client;
+
+    /**
+     * Constructor.
+     *
+     * @param  string $serviceUrl
+     * @param  integer $catalogNumber
+     * @param  integer $lbsUserNumber
+     * @return void
+     */
+    public function __construct ($serviceUrl, $catalogNumber, $lbsUserNumber)
+    {
+        $this->serviceUrl = $serviceUrl;
+        $this->catalogNumber = $catalogNumber;
+        $this->lbsUserNumber = $lbsUserNumber;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function authenticate ($username, $password)
+    {
+        $query = array(
+            'UK' => $username,
+            'PW' => $password,
+            'UN' => $this->lbsUserNumber,
+            'FNO' => $this->catalogNumber,
+            'LNG' => 'EN'
+        );
+        try {
+            $response = $this->getClient()->get($this->serviceUrl, array('query' => $query));
+        } catch (RequestException $e) {
+            throw new RuntimeException(null, -1, $e);
+        }
+        $attributes = $this->parseResponseBody($response->getBody());
+        return $attributes;
+    }
+
+    /**
+     * Return HTTP client.
+     *
+     * @return Client
+     */
+    public function getClient ()
+    {
+        if ($this->client === null) {
+            $this->client = new Client();
+        }
+        return $this->client;
+    }
+
+    /**
+     * Parse response body and user return attributes.
+     *
+     * Returns false on authentication failure.
+     *
+     * @param  string $body
+     * @return array|false
+     */
+    private function parseResponseBody ($body)
+    {
+        $response = @simplexml_load_string($body);
+        if ($response === false || $response->getName() !== 'AuthenticationResponse' || (string)$response->status !== 'OK') {
+            return false;
+        }
+        $attributes = array();
+        foreach ($response as $attribute) {
+            $attributes[$attribute->getName()] = (string)$attribute;
+        }
+        return $attributes;
+    }
+}
\ No newline at end of file
diff --git a/tests/unit-tests/data/lbs4authentication.error.response b/tests/unit-tests/data/lbs4authentication.error.response
new file mode 100644
index 0000000000000000000000000000000000000000..6af4cd127b9045d0dd489b0acaa4b6ffb2094214
--- /dev/null
+++ b/tests/unit-tests/data/lbs4authentication.error.response
@@ -0,0 +1,7 @@
+HTTP/1.1 200 OK
+Date: Wed, 06 May 2015 09:43:16 GMT
+Server: Apache/2.2.13 (Unix) mod_jk/1.2.28 mod_ssl/2.2.13 OpenSSL/0.9.8k PHP/5.2.11
+Content-Length: 168
+Content-Type: application/xml
+
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><AuthenticationResponse><status>NOK</status><error>Wrong password and/or number.</error></AuthenticationResponse>
\ No newline at end of file
diff --git a/tests/unit-tests/data/lbs4authentication.success.response b/tests/unit-tests/data/lbs4authentication.success.response
new file mode 100644
index 0000000000000000000000000000000000000000..7d048ffe719710f44bbc90b8a3825737f60b6b9b
--- /dev/null
+++ b/tests/unit-tests/data/lbs4authentication.success.response
@@ -0,0 +1,7 @@
+HTTP/1.1 200 OK
+Date: Wed, 06 May 2015 09:42:33 GMT
+Server: Apache/2.2.13 (Unix) mod_jk/1.2.28 mod_ssl/2.2.13 OpenSSL/0.9.8k PHP/5.2.11
+Content-Length: 232
+Content-Type: application/xml
+
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><AuthenticationResponse><status>OK</status><sessionID>c3ac4981-eb02-46f5-b092-d7261d08386f</sessionID><userKey>username</userKey><userGroup>20</userGroup></AuthenticationResponse>
\ No newline at end of file
diff --git a/tests/unit-tests/src/HAB/Pica/Auth/LBSAuthenticationTest.php b/tests/unit-tests/src/HAB/Pica/Auth/LBSAuthenticationTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..08c1e73a2743c5e8f4ae4a7fb55f652566877349
--- /dev/null
+++ b/tests/unit-tests/src/HAB/Pica/Auth/LBSAuthenticationTest.php
@@ -0,0 +1,68 @@
+<?php
+
+/**
+ * This file is part of PicaAuth.
+ *
+ * PicaAuth is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PicaAuth is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with PicaAuth.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author    David Maus <maus@hab.de>
+ * @copyright (c) 2015 by Herzog August Bibliothek Wolfenbüttel
+ * @license   http://www.gnu.org/licenses/gpl.txt GNU General Public License v3 or higher
+ */
+
+namespace HAB\Pica\Auth;
+
+use GuzzleHttp\Subscriber\Mock;
+
+use PHPUnit_Framework_TestCase as TestCase;
+
+/**
+ * Unit tests for the LBSAuthenitcation service module.
+ *
+ * @author    David Maus <maus@hab.de>
+ * @copyright (c) 2015 by Herzog August Bibliothek Wolfenbüttel
+ * @license   http://www.gnu.org/licenses/gpl.txt GNU General Public License v3 or higher
+ */
+class LBSAuthenticationTest extends TestCase
+{
+    /**
+     * @expectedException RuntimeException
+     */
+    public function testRuntimeExceptionOnRemoteError ()
+    {
+        $service = new LBSAuthentication('invalid://example.org/', 0, 0);
+        $response = new Mock(array('HTTP/1.1 500 Internal Server Error'));
+        $service->getClient()->getEmitter()->attach($response);
+        $service->authenticate('username', 'password');
+    }
+
+    public function testAuthenticationFailure ()
+    {
+        $service = new LBSAuthentication('invalid://example.org/', 0, 0);
+        $response = new Mock(array(file_get_contents(APP_TESTDIR . '/unit-tests/data/lbs4authentication.error.response')));
+        $service->getClient()->getEmitter()->attach($response);
+        $attributes = $service->authenticate('username', 'password');
+        $this->assertFalse($attributes);
+    }
+
+    public function testAuthenticationSuccess ()
+    {
+        $service = new LBSAuthentication('invalid://example.org/', 0, 0);
+        $response = new Mock(array(file_get_contents(APP_TESTDIR . '/unit-tests/data/lbs4authentication.success.response')));
+        $service->getClient()->getEmitter()->attach($response);
+        $attributes = $service->authenticate('username', 'password');
+        $this->assertInternalType('array', $attributes);
+        $this->assertNotEmpty($attributes);
+    }
+}
\ No newline at end of file