diff --git a/README.txt b/README.txt
index d48d9f7..a8b07bd 100644
--- a/README.txt
+++ b/README.txt
@@ -29,6 +29,8 @@ Installation
    activate the Web service client REST module.
  * If you want to use SOAP services you have to activate the Web service client
    SOAP module.
+ * To use OAuth (v1) authentication the OAuth module must be installed:
+   https://www.drupal.org/project/oauth.
 
 
 Web service decriptions
diff --git a/wsclient_rest/wsclient_rest.inc b/wsclient_rest/wsclient_rest.inc
index b44e709..1d1313c 100644
--- a/wsclient_rest/wsclient_rest.inc
+++ b/wsclient_rest/wsclient_rest.inc
@@ -33,17 +33,48 @@ public function client() {
       if (isset($settings['authentication'])) {
         // Handle each type of authentication.
         foreach ($settings['authentication'] as $auth => $auth_settings) {
-          // @todo Allow multiple authentications by implementing and using HttpClientCompositeAuth.
-          switch ($auth) {
-            case 'basic':
-            default:
-              $username = $auth_settings['username'];
-              $password = $auth_settings['password'];
-              $authentication = new HttpClientBasicAuth($username, $password);
-              break;
-            case 'oauth2':
-              $authentication = new HttpClientOAuth2($auth_settings);
-              break;
+          // @todo Remove this check once multiple authentications are
+          // implemented.
+          if ($auth == 'type') {
+            continue;
+          }
+
+          // @todo Remove this check once multiple authentications are
+          // implemeted. For now the switch would cause the last configured
+          // authentication type to be taken.
+          if ($auth == $settings['authentication']['type']) {
+            // @todo Allow multiple authentications by implementing and using
+            // HttpClientCompositeAuth.
+            switch ($auth) {
+              // OAuth v1 support using the OAuth module.
+              case 'oauth':
+                $api_key = variable_get('MYMODULE_apikey');
+                $api_secret = variable_get('MYMODULE_apisecret');
+                $api_params = array(
+                  // Will depend upon implementation.
+                );
+                $consumer = new DrupalOAuthConsumer($api_key, $api_secret, $api_params);
+                // Should return NULL if no saved token is available.
+                $access_token = MYMODULE_GET_SAVED_ACCESS_TOKEN();
+                $sig_method = DrupalOAuthClient::signatureMethod();
+
+                $authentication = new HttpClientOAuth($consumer, $access_token, $sig_method, TRUE, TRUE);
+                break;
+
+              // OAuth v2 support using the http_client module.
+              case 'oauth2':
+                $authentication = new HttpClientOAuth2($auth_settings);
+                break;
+
+              // Default authentication options from the http_client module.
+              case 'basic':
+              case 'wss':
+              default:
+                $username = $auth_settings['username'];
+                $password = $auth_settings['password'];
+                $authentication = new HttpClientBasicAuth($username, $password);
+                break;
+            }
           }
         }
       }
@@ -142,21 +173,21 @@ public function formAlter(&$form, &$form_state) {
             case 'send_formatter':
               $title = t('Request formatter (send_formatter)');
               $description = t('Choose how to serialize the request.');
-              $weight = 45;
+              $weight = 50;
               break;
             case 'receive_formatter':
               $title = t('Response formatter (receive_formatter)');
               $description = t('Choose how to parse the response.');
-              $weight = 50;
+              $weight = 55;
               break;
           }
-          $form[$formatter_type] = array(
+          $form['settings'][$formatter_type] = array(
             '#type' => 'fieldset',
             '#title' => $title,
             '#tree' => TRUE,
             '#weight' => $weight,
           );
-          $form[$formatter_type]['formatter'] = array(
+          $form['settings'][$formatter_type]['class'] = array(
             '#type' => 'select',
             '#title' => t('Formatter'),
             '#default_value' => $default_formatter,
@@ -262,18 +293,18 @@ public function formAlter(&$form, &$form_state) {
             ? $service->settings[$formatter_type]['settings']
             : array();
           // UI for settings.
-          $form[$formatter_type]['settings']['default_root'] = array(
+          $form['settings'][$formatter_type]['settings']['default_root'] = array(
             '#type' => 'textfield',
             '#title' => t('Default root'),
             '#default_value' => isset($formatter_settings['default_root']) ? $formatter_settings['default_root'] : $default_formatter_settings['default_root'],
             '#description' => t('Default root for created XML documents.'),
             '#states' => array(
               'visible' => array(
-                'select[name="' . $formatter_type . '[formatter]"]' => array('value' => 'WsclientRestXMLFormatter'),
+                'select[name="settings[' . $formatter_type . '][class]"]' => array('value' => 'WsclientRestXMLFormatter'),
               ),
             ),
           );
-          $form[$formatter_type]['settings']['adaptive_root'] = array(
+          $form['settings'][$formatter_type]['settings']['adaptive_root'] = array(
             '#type' => 'checkbox',
             '#title' => t('Adaptive root'),
             '#default_value' => isset($formatter_settings['adaptive_root']) ? $formatter_settings['adaptive_root'] : $default_formatter_settings['adaptive_root'],
@@ -286,7 +317,7 @@ public function formAlter(&$form, &$form_state) {
             ),
             '#states' => array(
               'visible' => array(
-                'select[name="' . $formatter_type . '[formatter]"]' => array('value' => 'WsclientRestXMLFormatter'),
+                'select[name="settings[' . $formatter_type . '][class]"]' => array('value' => 'WsclientRestXMLFormatter'),
               ),
             ),
           );
@@ -300,9 +331,9 @@ public function formSubmit($form, &$form_state) {
       case 'main':
         // Remove XML settings from the formatters that are not XML.
         foreach (array('send_formatter', 'receive_formatter') as $formatter_type) {
-          if ($form_state['values'][$formatter_type]['formatter'] != 'WsclientRestXMLFormatter') {
+          if ($form_state['values']['settings'][$formatter_type]['formatter'] != 'WsclientRestXMLFormatter') {
             foreach (array('default_root', 'adaptive_root') as $setting) {
-              unset($form_state['values'][$formatter_type]['settings'][$setting]);
+              unset($form_state['values']['settings'][$formatter_type]['settings'][$setting]);
             }
           }
         }
diff --git a/wsclient_rest/wsclient_rest.module b/wsclient_rest/wsclient_rest.module
index cc61307..6354aca 100644
--- a/wsclient_rest/wsclient_rest.module
+++ b/wsclient_rest/wsclient_rest.module
@@ -54,24 +54,6 @@ function wsclient_rest_operation_form_submit($form, &$form_state) {
 }
 
 /**
- * Form submit callback for the main form.
- */
-function wsclient_rest_main_form_submit($form, &$form_state) {
-  foreach (array('send_formatter', 'receive_formatter') as $formatter_type) {
-    // Make sure to avoid overridding of the custom formatter, defined in the settings.
-    if ($form_state['values'][$formatter_type]['formatter'] === 'custom') {
-      continue;
-    }
-    // Save settings in the service settings.
-    $formatter_settings = &$form_state['service']->settings[$formatter_type];
-    $formatter_settings['class'] = $form_state['values'][$formatter_type]['formatter'];
-    if (!empty($form_state['values'][$formatter_type]['settings'])) {
-      $formatter_settings['settings'] = $form_state['values'][$formatter_type]['settings'];
-    }
-  }
-}
-
-/**
  * Returns a list of formatters, suitable for use as form options.
  */
 function wsclient_rest_formatters_as_options() {
diff --git a/wsclient_ui/wsclient_ui.inc b/wsclient_ui/wsclient_ui.inc
index 0263a5a..b7e068a 100644
--- a/wsclient_ui/wsclient_ui.inc
+++ b/wsclient_ui/wsclient_ui.inc
@@ -181,7 +181,7 @@ function wsclient_service_form($form, &$form_state, $service, $op = 'edit') {
       '#caption' => t('Operations'),
       '#rows' => $rows,
       '#header' => $header,
-      '#weight' => 50,
+      '#weight' => 65,
     );
     // Add some table styling from Rules.
     $form['operations']['#attributes']['class'][] = 'rules-elements-table';
@@ -228,9 +228,302 @@ function wsclient_service_form($form, &$form_state, $service, $op = 'edit') {
       '#caption' => t('Data types'),
       '#rows' => $rows,
       '#header' => $header,
+      '#weight' => 70,
+    );
+
+    $settings = $service->settings;
+    // Simply naming the settings here to reflect the internal entity
+    // structure is enough to mean we don't need to worry about serializing
+    // it ourself.
+    $form['settings'] = array(
+      '#tree' => TRUE,
+      '#weight' => 45,
+    );
+    // Input for Authentication options.
+    $form['settings']['authentication'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Authentication'),
       '#weight' => 60,
     );
 
+    // @todo Remove authentication type once multiple authentications is implemented
+    // @see WSClientRESTEndpoint::client() => Allow multiple authentications by implementing and using HttpClientCompositeAuth.
+    $form['settings']['authentication']['type'] = array(
+      '#type' => 'select',
+      '#options' => array(
+        'none' => t("None"),
+        'basic' => t("Basic (htauth)"),
+        'wss' => t("WSS (Web Service Security)"),
+        'oauth2' => t("OAuth2"),
+      ),
+      '#default_value' => isset($settings['authentication']['type']) ? $settings['authentication']['type'] : 'none',
+    );
+    // OAuth v1 support using the OAuth module.
+    if (module_exists('oauth_common')) {
+      $form['settings']['authentication']['type']['#options']['oauth'] = t('OAuth');
+      // Reposition the 'oauth2' option so it's displayed after 'oauth' v1.
+      unset($form['settings']['authentication']['type']['#options']['oauth2']);
+      $form['settings']['authentication']['type']['#options']['oauth2'] = t('OAuth2');
+    }
+
+    $xpath = ':input[name="settings[authentication][type]"]';
+
+    $basic_states = array(
+      '#states' => array(
+        'visible' => array(
+          $xpath => array('value' => 'basic'),
+        ),
+      ),
+    );
+
+    $basic_settings = isset($settings['authentication']['basic']) ? $settings['authentication']['basic'] : array();
+
+    $form['settings']['authentication']['basic'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Basic HTAuth'),
+      '#description' => t('HTAuth requires http_client.module > 7.x-2.4'),
+    ) + $basic_states;
+    $form['settings']['authentication']['basic']['username'] = array(
+      '#type' => 'textfield',
+      '#title' => 'username',
+      '#default_value' => isset($basic_settings['username'])? $basic_settings['username'] : '',
+    );
+    $form['settings']['authentication']['basic']['password'] = array(
+      '#type' => 'textfield',
+      '#title' => 'password',
+      '#default_value' => isset($basic_settings['password'])? $basic_settings['password'] : '',
+    );
+
+    $wss_settings = isset($settings['authentication']['wss']) ? $settings['authentication']['wss'] : array();
+
+    $form['settings']['authentication']['wss'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('WSS (Web Services Security)'),
+      '#states' => array(
+        'visible' => array(
+          $xpath => array('value' => 'wss'),
+        ),
+      ),
+    );
+    $form['settings']['authentication']['wss']['username'] = array(
+      '#type' => 'textfield',
+      '#title' => 'username',
+      '#default_value' => isset($wss_settings['username'])? $wss_settings['username'] : '',
+    );
+    $form['settings']['authentication']['wss']['password'] = array(
+      '#type' => 'textfield',
+      '#title' => 'password',
+      '#default_value' => isset($wss_settings['password'])? $wss_settings['password'] : '',
+    );
+
+    // Optional OAuth.
+    if (module_exists('oauth_common')) {
+      $oauth_states = array(
+        '#states' => array(
+          'visible' => array(
+            $xpath => array('value' => 'oauth'),
+          ),
+        ),
+      );
+
+      $xpath_auth_flow = ':input[name="settings[authentication][oauth][auth_flow]"]';
+
+      $oauth_states_server_side = array(
+        '#states' => array(
+          'visible' => array(
+            $xpath => array('value' => 'oauth'),
+            $xpath_auth_flow => array('value' => 'server-side'),
+          ),
+        ),
+      );
+
+      $oauth_states_user_password = array(
+        '#states' => array(
+          'visible' => array(
+            $xpath => array('value' => 'oauth'),
+            $xpath_auth_flow => array('value' => 'user-password'),
+          ),
+        ),
+      );
+
+      $form['settings']['authentication']['oauth'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('OAuth'),
+      ) + $oauth_states;
+
+      $oauth_settings = isset($settings['authentication']['oauth']) ? $settings['authentication']['oauth'] : array();
+
+      $form['settings']['authentication']['oauth']['auth_flow'] = array(
+        '#type' => 'select',
+        '#title' => 'auth_flow',
+        '#options' => array(
+          'client-credentials' => 'client-credentials',
+          'server-side' => 'server_side',
+          'user-password' => 'user_password',
+        ),
+        '#default_value' => isset($oauth_settings['auth_flow']) ? $oauth_settings['auth_flow'] : '',
+      );
+      $form['settings']['authentication']['oauth']['token_endpoint'] = array(
+        '#type' => 'textfield',
+        '#title' => 'token_endpoint',
+        '#default_value' => isset($oauth_settings['token_endpoint']) ? $oauth_settings['token_endpoint'] : '',
+        '#description' => t('E.g. https://server.org/oauth/token.'),
+        '#element_validate' => array('wsclient_ui_element_url_validate'),
+      );
+      $form['settings']['authentication']['oauth']['client_id'] = array(
+        '#type' => 'textfield',
+        '#title' => 'Client key',
+        '#default_value' => isset($oauth_settings['client_key']) ? $oauth_settings['client_id'] : '',
+        '#description' => t('The client ID as registered on the oauth server.'),
+      );
+      $form['settings']['authentication']['oauth']['client_secret'] = array(
+        '#type' => 'textfield',
+        '#title' => 'Client secret',
+        '#default_value' => isset($oauth_settings['client_secret']) ? $oauth_settings['client_secret'] : '',
+        '#description' => t('The client secret as registered on the oauth server.'),
+      );
+      $form['settings']['authentication']['oauth']['scope'] = array(
+        '#type' => 'textfield',
+        '#title' => 'scope',
+        '#default_value' => isset($oauth_settings['scope']) ? $oauth_settings['scope'] : '',
+        '#description' => t('Space separated list of scopes.'),
+      );
+      $form['settings']['authentication']['oauth']['query_auth'] = array(
+        '#type' => 'select',
+        '#title' => 'Query auth',
+        '#options' => array(0 => t('No'), 1 => t('Yes')),
+        '#default_value' => isset($oauth_settings['query_auth']) ? $oauth_settings['query_auth'] : 0,
+        '#description' => t("Yes will make the access token be set on the query, otherwise it'll be set on the headers."),
+      );
+      $form['settings']['authentication']['oauth']['redirect_uri'] = array(
+        '#type' => 'textfield',
+        '#title' => 'Redirect URI',
+        '#default_value' => isset($oauth_settings['redirect_uri']) ? $oauth_settings['redirect_uri'] : '',
+        '#description' => t('E.g. https://client.org/oauth/authorized. Only needed for server-side auth_flow.'),
+      ) + $oauth_states_server_side;
+      $form['settings']['authentication']['oauth']['authorization_endpoint'] = array(
+        '#type' => 'textfield',
+        '#title' => 'Authorization endpoint',
+        '#default_value' => isset($oauth_settings['authorization_endpoint']) ? $oauth_settings['authorization_endpoint'] : '',
+        '#description' => t('E.g. https://server.org/oauth/authorize. Only needed for server-side auth_flow.'),
+      ) + $oauth_states_server_side;
+      $form['settings']['authentication']['oauth']['username'] = array(
+        '#type' => 'textfield',
+        '#title' => 'Username',
+        '#default_value' => isset($oauth_settings['username']) ? $oauth_settings['username'] : '',
+        '#description' => t('Username of resource owner on the oauth server. Only needed for user-password auth_flow.'),
+      ) + $oauth_states_user_password;
+      $form['settings']['authentication']['oauth']['password'] = array(
+        '#type' => 'textfield',
+        '#title' => 'Password',
+        '#default_value' => isset($oauth_settings['password']) ? $oauth_settings['password'] : '',
+        '#description' => t('Password of resource owner on the oauth server. Only needed for user-password auth_flow.'),
+      ) + $oauth_states_user_password;
+    }
+
+    $oauth2_states = array(
+      '#states' => array(
+        'visible' => array(
+          $xpath => array('value' => 'oauth2'),
+        ),
+      ),
+    );
+
+    $xpath_auth_flow = ':input[name="settings[authentication][oauth2][auth_flow]"]';
+
+    $oauth2_states_server_side = array(
+      '#states' => array(
+        'visible' => array(
+          $xpath => array('value' => 'oauth2'),
+          $xpath_auth_flow => array('value' => 'server-side'),
+        ),
+      ),
+    );
+
+    $oauth2_states_user_password = array(
+      '#states' => array(
+        'visible' => array(
+          $xpath => array('value' => 'oauth2'),
+          $xpath_auth_flow => array('value' => 'user-password'),
+        ),
+      ),
+    );
+
+    $form['settings']['authentication']['oauth2'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('OAuth2'),
+    ) + $oauth2_states;
+
+    $oauth_settings = isset($settings['authentication']['oauth2']) ? $settings['authentication']['oauth2'] : array();
+
+    $form['settings']['authentication']['oauth2']['auth_flow'] = array(
+      '#type' => 'select',
+      '#title' => 'auth_flow',
+      '#options' => array(
+        'client-credentials' => 'client-credentials',
+        'server-side' => 'server_side',
+        'user-password' => 'user_password',
+      ),
+      '#default_value' => isset($oauth_settings['auth_flow']) ? $oauth_settings['auth_flow'] : '',
+    );
+    $form['settings']['authentication']['oauth2']['token_endpoint'] = array(
+      '#type' => 'textfield',
+      '#title' => 'token_endpoint',
+      '#default_value' => isset($oauth_settings['token_endpoint']) ? $oauth_settings['token_endpoint'] : '',
+      '#description' => t('E.g. https://server.org/oauth2/token.'),
+      '#element_validate' => array('wsclient_ui_element_url_validate'),
+    );
+
+    $form['settings']['authentication']['oauth2']['client_id'] = array(
+      '#type' => 'textfield',
+      '#title' => 'client_id',
+      '#default_value' => isset($oauth_settings['client_id']) ? $oauth_settings['client_id'] : '',
+      '#description' => t('The client ID as registered on the oauth2 server.'),
+    );
+    $form['settings']['authentication']['oauth2']['client_secret'] = array(
+      '#type' => 'textfield',
+      '#title' => 'client_secret',
+      '#default_value' => isset($oauth_settings['client_secret']) ? $oauth_settings['client_secret'] : '',
+      '#description' => t('The client secret as registered on the oauth2 server.'),
+    );
+    $form['settings']['authentication']['oauth2']['scope'] = array(
+      '#type' => 'textfield',
+      '#title' => 'scope',
+      '#default_value' => isset($oauth_settings['scope']) ? $oauth_settings['scope'] : '',
+      '#description' => t('Space separated list of scopes.'),
+    );
+    $form['settings']['authentication']['oauth2']['query_auth'] = array(
+      '#type' => 'select',
+      '#title' => 'query_auth',
+      '#options' => array(0 => t('No'), 1 => t('Yes')),
+      '#default_value' => isset($oauth_settings['query_auth']) ? $oauth_settings['query_auth'] : 0,
+      '#description' => t("Yes will make the access token be set on the query, otherwise it'll be set on the headers."),
+    );
+    $form['settings']['authentication']['oauth2']['redirect_uri'] = array(
+      '#type' => 'textfield',
+      '#title' => 'redirect_uri',
+      '#default_value' => isset($oauth_settings['redirect_uri']) ? $oauth_settings['redirect_uri'] : '',
+      '#description' => t('E.g. https://client.org/oauth2/authorized. Only needed for server-side auth_flow.'),
+    ) + $oauth2_states_server_side;
+    $form['settings']['authentication']['oauth2']['authorization_endpoint'] = array(
+      '#type' => 'textfield',
+      '#title' => 'authorization_endpoint',
+      '#default_value' => isset($oauth_settings['authorization_endpoint']) ? $oauth_settings['authorization_endpoint'] : '',
+      '#description' => t('E.g. https://server.org/oauth2/authorize. Only needed for server-side auth_flow.'),
+    ) + $oauth2_states_server_side;
+    $form['settings']['authentication']['oauth2']['username'] = array(
+      '#type' => 'textfield',
+      '#title' => 'username',
+      '#default_value' => isset($oauth_settings['username']) ? $oauth_settings['username'] : '',
+      '#description' => t('Username of resource owner on the oauth2 server. Only needed for user-password auth_flow.'),
+    ) + $oauth2_states_user_password;
+    $form['settings']['authentication']['oauth2']['password'] = array(
+      '#type' => 'textfield',
+      '#title' => 'password',
+      '#default_value' => isset($oauth_settings['password']) ? $oauth_settings['password'] : '',
+      '#description' => t('Password of resource owner on the oauth2 server. Only needed for user-password auth_flow.'),
+    ) + $oauth2_states_user_password;
+
     // Input for global service parameters.
     $form['global_parameters'] = array(
       '#tree' => TRUE,
