The OAuth2 plugin provides authentication using OAuth2 providers (Google, GitHub, Azure AD, etc.), integrating seamlessly with Rusty Beam's authorization system.
This plugin implements the OAuth2 authorization code flow for authentication with any OAuth2-compliant provider. It handles login, callback, logout, and status endpoints while maintaining session state. The plugin sets the authenticated_user
metadata that can be used by the authorization plugin for access control decisions.
Add the OAuth2 plugin to your host configuration before the authorization plugin:
<!-- Google OAuth2 configuration -->
<td itemprop="plugin" itemscope itemtype="https://rustybeam.net/schema/OAuth2Plugin">
<span itemprop="library">file://./plugins/librusty_beam_oauth2.so</span>
<span itemprop="clientIdEnv">GOOGLE_CLIENT_ID</span>
<span itemprop="clientSecretEnv">GOOGLE_CLIENT_SECRET</span>
<span itemprop="redirectUriEnv">GOOGLE_OAUTH2_CALLBACK</span>
</td>
<!-- GitHub OAuth2 configuration with custom login path -->
<td itemprop="plugin" itemscope itemtype="https://rustybeam.net/schema/OAuth2Plugin">
<span itemprop="library">file://./plugins/librusty_beam_oauth2.so</span>
<span itemprop="name">github-oauth2</span>
<span itemprop="clientIdEnv">GITHUB_CLIENT_ID</span>
<span itemprop="clientSecretEnv">GITHUB_CLIENT_SECRET</span>
<span itemprop="redirectUriEnv">GITHUB_REDIRECT_URI</span>
<span itemprop="loginPath">/auth/github/signin</span>
</td>
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
clientIdEnv |
String | Yes | - | Environment variable name to read OAuth2 client ID from |
clientSecretEnv |
String | Yes | - | Environment variable name to read OAuth2 client secret from |
redirectUriEnv |
String | Yes | - | Environment variable name to read OAuth2 redirect URI from |
name |
String | No | oauth2 | Plugin instance name |
loginPath |
String | No | /auth/{name}/login | Path where login requests will be handled |
authenticated_user
metadata that the authorization plugin uses for access control decisions.
The plugin reads all OAuth2 configuration from environment variables for security. You must specify which environment variables to use via the clientIdEnv
, clientSecretEnv
, and redirectUriEnv
configuration parameters.
GOOGLE_CLIENT_ID
and another reading from GITHUB_CLIENT_ID
.
Example setup for common providers:
The plugin provides the following endpoints:
Endpoint | Method | Description | Response |
---|---|---|---|
{loginPath} |
GET | Initiates OAuth2 flow | 302 redirect to OAuth provider |
{callback path} |
GET | OAuth2 callback handler | 302 redirect to return URL or / |
/auth/logout |
POST | Destroys session | 302 redirect to return URL or / |
/auth/user |
GET | Returns current user information | HTML with schema.org/Person microdata |
/auth/{name}/login
but can be customized using the loginPath
configurationGOOGLE_OAUTH2_CALLBACK
is set to https://example.com/auth/google/callback
, the callback endpoint will be /auth/google/callback
/auth/user
endpoint returns HTML with schema.org/Person microdata only if there's an active session, otherwise passes through<!-- Default login path -->
<a href="/auth/oauth2/login?return_to=/dashboard" class="login-btn">
Login with OAuth
</a>
<!-- Custom login path (when loginPath is configured) -->
<a href="/auth/github/signin?return_to=/dashboard" class="login-btn">
Login with GitHub
</a>
async function checkAuth() {
const response = await fetch('/auth/user');
if (response.ok) {
const html = await response.text();
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
// Extract user info from microdata
const userEl = doc.querySelector('[itemtype="https://schema.org/Person"]');
if (userEl) {
const email = userEl.querySelector('[itemprop="email"]')?.textContent;
const name = userEl.querySelector('[itemprop="name"]')?.textContent;
console.log(`Logged in as: ${name} (${email})`);
// Show authenticated UI
}
} else {
// User not authenticated - show login button
}
}
The /auth/user
endpoint returns HTML with schema.org/Person microdata when a user is authenticated:
<!DOCTYPE html>
<html>
<head>
<title>User Information</title>
</head>
<body>
<div itemscope itemtype="https://schema.org/Person">
<p>Email: <span itemprop="email">user@example.com</span></p>
<p>Name: <span itemprop="name">John Doe</span></p>
<p>Image: <span itemprop="image">https://example.com/avatar.jpg</span></p>
</div>
</body>
</html>
async function logout() {
const response = await fetch('/auth/logout?return_to=/', {
method: 'POST'
});
if (response.ok) {
window.location.href = '/';
}
}
In your authorization configuration, you can grant permissions to specific users by email:
<tr itemscope itemtype="https://rustybeam.net/schema/AuthorizationRule">
<td itemprop="username">user@gmail.com</td>
<td itemprop="path">/admin/*</td>
<td></td>
<td><ul><li itemprop="method">GET</li></ul></td>
<td itemprop="action">allow</td>
</tr>
The OAuth2 plugin integrates primarily with:
authenticated_user
metadata containing the user's email addressSessions are managed in-memory with the following characteristics:
Issue | Possible Cause | Solution |
---|---|---|
500 Error on login | Missing client_id or client_secret | Ensure OAuth2 credentials are configured correctly |
Invalid redirect URI error | Mismatch between configured and provider URIs | Verify redirect_uri matches exactly in both places |
403 on callback | Invalid or missing state parameter | Check for cookie issues or middleware interference |
User not authorized after login | Plugin order incorrect | Ensure OAuth2 plugin is before authorization plugin |
Enable verbose mode to see detailed OAuth2 flow information:
cargo run -- -v config/config.html