A PHP library for authenticating with CommunitySolidServer using OpenID Connect (OIDC) with Demonstrating Proof-of-Possession (DPoP) support.
- Full OpenID Connect Authorization Code Flow implementation
- Demonstrating Proof-of-Possession (DPoP) support for enhanced security
- Automatic OIDC discovery
- ID Token validation with JWKS
- Comprehensive error handling with custom exceptions
- Support for custom scopes and claims
- Compatible with CommunitySolidServer and other Solid-OIDC providers
- PHP 8.1 or higher
- cURL extension
- JSON extension
- OpenSSL extension
- Composer for dependency management
- Clone or download this library
- Install dependencies using Composer:
composer install
<?php
require_once 'vendor/autoload.php';
use SolidOidc\SolidOidcClient;
use SolidOidc\SolidOidcException;
// Initialize the client
$client = new SolidOidcClient(
'https://solidcommunity.net', // Issuer URL
'your-client-id', // Client ID
'your-client-secret', // Client Secret
'http://localhost:8080/callback' // Redirect URI
);
try {
// Perform OIDC discovery
$client->discover();
// Generate authorization URL
$state = bin2hex(random_bytes(16));
$authUrl = $client->getAuthorizationUrl($state, ['openid', 'profile']);
// Redirect user to authorization URL
header('Location: ' . $authUrl);
} catch (SolidOidcException $e) {
echo "Error: " . $e->getMessage();
}
<?php
// In your callback handler (e.g., callback.php)
if (isset($_GET['code']) && isset($_GET['state'])) {
try {
// Exchange code for tokens
$tokens = $client->handleAuthorizationResponse($_GET['code'], $_GET['state']);
// Access the tokens
$accessToken = $tokens['access_token'];
$idToken = $tokens['id_token'];
$idTokenClaims = $tokens['id_token_claims'];
// Get user information
$userInfo = $client->getUserInfo($accessToken);
// Store tokens securely (session, database, etc.)
$_SESSION['access_token'] = $accessToken;
$_SESSION['user_info'] = $userInfo;
} catch (SolidOidcException $e) {
echo "Authentication failed: " . $e->getMessage();
}
}
Before using this library, you need to register your application with the Solid OIDC provider:
- For CommunitySolidServer: Visit your pod's settings or use the registration endpoint
- For SolidCommunity.net: Use their client registration interface
- For custom instances: Follow the provider's client registration process
You'll need to provide:
- Client Name: A human-readable name for your application
- Redirect URIs: The callback URLs where users will be redirected after authentication
- Scopes: The permissions your application requires (e.g.,
openid
,profile
,email
)
$config = [
'issuer_url' => 'https://your-solid-server.example.com',
'client_id' => 'your-registered-client-id',
'client_secret' => 'your-client-secret',
'redirect_uri' => 'https://your-app.example.com/callback'
];
public function __construct(
string $issuerUrl,
string $clientId,
string $clientSecret,
string $redirectUri
)
Parameters:
$issuerUrl
: The base URL of the OIDC issuer (e.g.,https://solidcommunity.net
)$clientId
: Your registered client identifier$clientSecret
: Your client secret (for confidential clients)$redirectUri
: The callback URL registered with the provider
Fetches and parses the OIDC discovery document from the provider's well-known endpoint.
Throws: SolidOidcException
if discovery fails
Generates the authorization URL for redirecting users to the OIDC provider.
Parameters:
$state
: A unique, unguessable string for CSRF protection$scopes
: Array of requested OAuth 2.0 scopes
Returns: The complete authorization URL
Throws: SolidOidcException
if discovery hasn't been performed
Exchanges the authorization code for tokens and validates the ID token.
Parameters:
$code
: The authorization code from the callback$state
: The state parameter from the callback
Returns: Array containing:
access_token
: The access token for API requestsid_token
: The ID token (JWT) containing user identity claimsrefresh_token
: The refresh token (if available)token_type
: Token type (usually "Bearer")expires_in
: Token lifetime in secondsid_token_claims
: Decoded and validated ID token claims
Throws: SolidOidcException
for authentication or validation failures
Retrieves user profile information from the userinfo endpoint.
Parameters:
$accessToken
: A valid access token
Returns: Array of user profile information
Throws: SolidOidcException
if the request fails
The library uses custom exceptions for better error handling:
use SolidOidc\SolidOidcException;
try {
// Your OIDC operations
} catch (SolidOidcException $e) {
echo "Error: " . $e->getMessage();
echo "Code: " . $e->getErrorCode();
// Get additional context
$context = $e->getContext();
if ($context) {
print_r($context);
}
}
DISCOVERY_FAILED
: Issues with fetching or parsing the discovery documentAUTHENTICATION_FAILED
: Problems during the authentication flowTOKEN_VALIDATION_FAILED
: ID token validation errorsDPOP_FAILED
: DPoP-related failuresHTTP_REQUEST_FAILED
: Network or HTTP errors
Always use a cryptographically secure random state parameter:
$state = bin2hex(random_bytes(16));
// Store $state in session for validation
$_SESSION['oauth_state'] = $state;
Validate the state parameter in your callback:
if ($_GET['state'] !== $_SESSION['oauth_state']) {
throw new Exception('Invalid state parameter - possible CSRF attack');
}
- Never store tokens in client-side storage (localStorage, cookies without HttpOnly flag)
- Use secure session storage or encrypted database storage
- Implement token expiration handling
- Consider using refresh tokens for long-lived sessions
- All communication must use HTTPS in production
- Redirect URIs must use HTTPS (except for localhost during development)
- Validate SSL certificates (don't disable SSL verification)
This library automatically handles DPoP (Demonstrating Proof-of-Possession) which:
- Binds access tokens to the client
- Prevents token replay attacks
- Provides cryptographic proof of token possession
See examples/simple_auth.php
for a complete working example.
See examples/advanced_auth.php
for advanced features including:
- Custom scopes
- Resource access
- Error handling
- Token information display
- Verify the issuer URL is correct and accessible
- Check that the server supports OIDC discovery
- Ensure network connectivity and SSL certificates are valid
- Verify client ID and secret are correct
- Check that redirect URI matches exactly what's registered
- Ensure the authorization code hasn't expired
- Check system clock synchronization
- Verify JWKS endpoint is accessible
- Ensure ID token hasn't expired
- Verify OpenSSL extension is installed and working
- Check that the server supports DPoP
- Ensure proper key generation and signing
Enable verbose error reporting for debugging:
// Enable all error reporting
error_reporting(E_ALL);
ini_set('display_errors', 1);
// Use try-catch blocks to capture detailed error information
try {
$client->discover();
} catch (SolidOidcException $e) {
echo "Detailed error: " . $e->getMessage() . "\n";
echo "Error code: " . $e->getErrorCode() . "\n";
echo "Context: " . json_encode($e->getContext(), JSON_PRETTY_PRINT) . "\n";
}
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
This project is open source. Please check the LICENSE file for details.
For issues and questions:
- Check the troubleshooting section above
- Review the examples for proper usage
- Create an issue with detailed error information and context
- Initial release
- Full OIDC Authorization Code Flow support
- DPoP implementation
- Comprehensive error handling
- Examples and documentation