Authentication System
When to Use
Understanding how Drupal identifies users and when to implement custom authentication providers (OAuth, SAML, LDAP, API keys).
Decision
| If you need... | Use... | Why |
|---|---|---|
| Standard cookie-based auth | Core user module | Built-in, secure, handles sessions |
| API authentication | HTTP Basic or custom provider | Stateless, suitable for REST/JSON API |
| OAuth/SAML/LDAP | Contrib modules | Proven implementations: simple_oauth, simplesamlphp_auth, ldap |
| Two-factor auth | TFA contrib module | Security layer on top of primary auth |
| Custom auth mechanism | AuthenticationProviderInterface | Full control, integrate with external systems |
Pattern
Custom authentication provider:
// src/Authentication/Provider/ApiKeyAuth.php
namespace Drupal\mymodule\Authentication\Provider;
use Drupal\Core\Authentication\AuthenticationProviderInterface;
use Symfony\Component\HttpFoundation\Request;
class ApiKeyAuth implements AuthenticationProviderInterface {
public function applies(Request $request) {
// Only apply if X-API-Key header present
return $request->headers->has('X-API-Key');
}
public function authenticate(Request $request) {
$api_key = $request->headers->get('X-API-Key');
// Validate API key and load user
$uid = $this->validateApiKey($api_key);
if ($uid) {
return User::load($uid);
}
return NULL; // Authentication failed
}
protected function validateApiKey($key) {
// Query for user with matching API key
$query = \Drupal::entityQuery('user')
->accessCheck(FALSE)
->condition('field_api_key', $key)
->condition('status', 1)
->range(0, 1);
$uids = $query->execute();
return $uids ? reset($uids) : NULL;
}
}
Register in mymodule.services.yml:
services:
mymodule.authentication.api_key:
class: Drupal\mymodule\Authentication\Provider\ApiKeyAuth
tags:
- { name: authentication_provider, priority: 100 }
/core/lib/Drupal/Core/Authentication/AuthenticationManager.php
Common Mistakes
- Implementing custom auth when contrib exists -- Use
simple_oauthfor OAuth, etc. - Not using flood control -- Brute force attacks succeed
- Storing passwords in plain text -- CRITICAL: Use
\Drupal::service('password')->hash() - Weak password requirements -- Enforce complexity via
password_policymodule - Not invalidating sessions on logout -- Session fixation vulnerability
- Authentication without authorization -- Auth identifies user; still need access checks
See Also
- Reference:
/core/modules/user/src/Entity/User.php - Session Management for session security
- Reference: https://www.drupal.org/docs/8/modules/simple-oauth