Authentication Patterns
Understanding different authentication types: form-based, SSO/SAML, OAuth, certificates, and MFA
Before implementing the MCP server, understand the authentication patterns encountered in academic research. This chapter covers five fundamental patterns and how to recognize them.
Pattern 1: Form-Based Authentication
The simplest and most common pattern: username and password submitted via HTML form.
Technical Flow
Browser loads login page
Navigate to the authentication endpoint and render the login form.
User enters credentials
Fill username and password fields in the HTML form.
Form submits to authentication endpoint
POST request sends credentials to server for validation.
Server validates credentials
Backend checks username and password against user database.
Server sets session cookies
Authenticated session tokens stored in browser cookies.
Browser redirects to authenticated area
User gains access to protected resources.
Automation Strategy
// Playwright automation example
await page.goto('https://university.edu/login');
await page.fill('input[name="username"]', username);
await page.fill('input[name="password"]', password);
await page.click('button[type="submit"]');
await page.waitForNavigation();
// Session cookies now stored in browser contextCommon Variations
Challenge: Hidden form field with anti-forgery token.
Solution: Extract token from page and include in submission.
// Extract CSRF token
const csrfToken = await page.getAttribute(
'input[name="csrf_token"]',
'value'
);
// Submit with token
await page.fill('input[name="username"]', username);
await page.fill('input[name="password"]', password);
await page.click('button[type="submit"]');Challenge: Credentials sent via AJAX instead of form POST.
Solution: Wait for network request completion.
// Wait for AJAX request
await Promise.all([
page.waitForResponse(resp =>
resp.url().includes('/api/login') && resp.status() === 200
),
page.click('button#login')
]);Challenge: Username on page 1, password on page 2.
Solution: Handle sequential navigation.
// Step 1: Username
await page.fill('input[name="username"]', username);
await page.click('button:has-text("Next")');
await page.waitForLoadState('networkidle');
// Step 2: Password
await page.fill('input[name="password"]', password);
await page.click('button:has-text("Sign In")');Challenge: Checkbox may extend session lifetime.
Solution: Enable for longer session persistence.
// Enable "Remember Me"
await page.check('input[name="remember"]');
await page.click('button[type="submit"]');
// Session cookies persist beyond browser closeDetection Tips: Look for <form> elements with action pointing to login endpoints, input fields with type="password", and POST requests containing credentials in the Network tab.
Pattern 2: SSO/SAML Flows
Academic institutions commonly use SAML-based SSO for federated authentication.
Technical Flow
The SAML authentication flow involves multiple redirects between Service Provider (SP) and Identity Provider (IdP):
User visits Service Provider
Access platform like ScienceDirect requiring institutional login.
SP redirects to Identity Provider
Redirect includes SAML request for authentication.
User authenticates at IdP
Log in using university credentials.
IdP generates SAML assertion
Creates signed XML document proving identity.
IdP redirects back to SP
SAML response contains authentication assertion.
SP validates assertion
Verifies signature and creates authenticated session.
Automation Strategy
// Handle SAML redirect flow
await page.goto('https://www.sciencedirect.com/');
await page.click('a:has-text("Institutional Login")');
// Wait for redirect to IdP
await page.waitForURL(/university\.edu\/idp/);
// Authenticate at IdP
await page.fill('#username', username);
await page.fill('#password', password);
await page.click('button[name="submit"]');
// Wait for SAML redirect back to SP
await page.waitForURL(/sciencedirect\.com/);
// Now authenticatedSAML Characteristics
Key indicators of SAML-based authentication:
- Multiple redirects (SP → IdP → SP)
- URLs containing
SAMLRequestorSAMLResponseparameters - IdP URL typically contains
/idp/or/sso/ - Long base64-encoded XML payloads in URLs
Debugging SAML
Use browser DevTools Network tab to trace redirects:
// Monitor all redirects
page.on('response', response => {
if (response.status() >= 300 && response.status() < 400) {
console.log(`Redirect: ${response.url()}`);
console.log(`Location: ${response.headers()['location']}`);
}
});Install SAML-tracer browser extension to decode SAML messages:
Features:
- Decodes base64-encoded SAML requests/responses
- Shows XML assertion content
- Displays signature verification status
- Timestamps each redirect step
Look for SAMLResponse form fields in POST requests:
// Intercept SAML response
await page.route('**/*', async (route, request) => {
const postData = request.postData();
if (postData?.includes('SAMLResponse')) {
console.log('SAML Response detected');
// Decode base64 to inspect XML
}
await route.continue();
});Check for assertion validation errors in SP logs:
Common errors:
- Signature verification failed
- Assertion expired
- Invalid recipient URL
- Missing required attributes
Pattern 3: OAuth 2.0 / OpenID Connect
Modern platforms increasingly use OAuth 2.0 and OIDC for authentication.
Technical Flow (Authorization Code Flow)
User clicks "Login with University"
Initiates OAuth authorization flow.
Redirects to OAuth authorization endpoint
Application requests specific scopes (permissions).
User authenticates and consents
Login at provider and approve requested permissions.
Redirects back with authorization code
Temporary code included in callback URL.
App exchanges code for access token
Backend exchanges code for JWT access token.
App uses access token for API requests
Token included in Authorization header for authenticated requests.
Automation Strategy
// OAuth flow automation
const authUrl = 'https://provider.com/oauth/authorize?' +
'client_id=xyz&redirect_uri=https://app.com/callback&' +
'response_type=code&scope=openid profile';
await page.goto(authUrl);
// Handle IdP login page
await page.fill('#email', email);
await page.fill('#password', password);
await page.click('#submit');
// Wait for consent page (may be skipped if previously granted)
if (await page.isVisible('button:has-text("Allow")')) {
await page.click('button:has-text("Allow")');
}
// Wait for redirect to callback URL
await page.waitForURL(/app\.com\/callback/);
// Extract authorization code from URL
const url = new URL(page.url());
const code = url.searchParams.get('code');
// Exchange code for token (app handles this)OAuth Characteristics
Key indicators of OAuth-based authentication:
- Query parameters like
client_id,redirect_uri,code - Consent screens showing requested permissions
- Tokens typically JWT format (base64-encoded JSON)
- Refresh tokens allow long-lived access
Token Management
Security Best Practices: Store access tokens securely, implement refresh logic before expiration, handle token revocation gracefully, and never expose tokens in logs or URLs.
// Token refresh pattern
async function getValidToken() {
if (isTokenExpired(accessToken)) {
// Refresh token before expiration
const response = await fetch('https://provider.com/oauth/token', {
method: 'POST',
body: JSON.stringify({
grant_type: 'refresh_token',
refresh_token: refreshToken,
client_id: clientId,
client_secret: clientSecret
})
});
const data = await response.json();
accessToken = data.access_token;
refreshToken = data.refresh_token;
}
return accessToken;
}Pattern 4: Certificate-Based Authentication
Some institutional resources use client certificates for authentication.
Technical Flow
Server requests client certificate
During TLS handshake, server asks for client certificate.
Browser presents certificate
Retrieves certificate from user's certificate store.
Server validates certificate
Checks certificate against trusted Certificate Authorities.
Connection established with mTLS
Mutual TLS provides two-way authentication.
Automation Strategy
// Launch browser with client certificate
const context = await browser.newContext({
clientCertificates: [{
origin: 'https://secure-library.edu',
certPath: '/path/to/client-cert.pem',
keyPath: '/path/to/client-key.pem',
}]
});
const page = await context.newPage();
await page.goto('https://secure-library.edu');
// Certificate automatically presentedCertificate Characteristics
Key indicators of certificate-based authentication:
- Browser shows certificate selection dialog
- URLs often use
https://with specific domain requirements - No traditional username/password form
- Certificate errors if cert invalid or not trusted
Security Considerations: Private keys must be kept secure. Certificates have expiration dates (monitor and renew). Revoked certificates must be removed. Never share private keys.
Pattern 5: Multi-Factor Authentication (MFA)
MFA adds a second verification factor beyond passwords.
Common MFA Types
SMS/Email Codes
One-time codes sent to registered contact method.
Authenticator Apps
TOTP codes from Google Authenticator, Authy, etc.
Push Notifications
Approve login from mobile app notification.
Hardware Tokens
Physical devices like YubiKey.
Biometrics
Fingerprint or face recognition.
Automation Strategies
Best for automation: TOTP codes can be generated programmatically.
import speakeasy from 'speakeasy';
// Generate TOTP code from stored secret
const token = speakeasy.totp({
secret: process.env.TOTP_SECRET,
encoding: 'base32'
});
// Enter code in MFA form
await page.fill('input[name="code"]', token);
await page.click('button[type="submit"]');Human-in-the-loop required: Wait for user approval.
// Trigger MFA prompt
await page.click('button:has-text("Send Push")');
// Wait for user to approve on device
console.log('Approve the push notification on your device...');
await page.waitForNavigation({ timeout: 60000 });Interactive input: Prompt user to enter received code.
// Trigger SMS
await page.click('button:has-text("Send SMS")');
// Prompt user to enter code
const readline = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
const code = await new Promise(resolve => {
readline.question('Enter SMS code: ', resolve);
});
await page.fill('input[name="sms_code"]', code);
await page.click('button[type="submit"]');
readline.close();MFA Best Practices
Recommended Approach: Prefer TOTP over SMS (more secure and automatable). Store TOTP secrets in secure credential store. Implement "Remember This Device" when available. Have fallback for MFA failures. Log MFA events for security audit.
Pattern Recognition in the Wild
When encountering a new authentication system, follow this systematic approach:
Open DevTools Network Tab
Watch for authentication requests and responses.
Identify Redirects
Trace the authentication flow through redirect chain.
Check for Known Patterns
Look for indicators of SAML, OAuth, form POST, or certificates.
Inspect Cookies
Note which cookies are set after successful authentication.
Test Session Persistence
Close and reopen browser with cookies to verify session lifetime.
Document the Flow
Create step-by-step manual procedure for reference.
Tools for Analysis
Browser DevTools (Network, Application tabs)
- Monitor all HTTP requests and responses
- Inspect cookies, localStorage, sessionStorage
- View redirect chains
- Examine request/response headers
SAML-tracer extension
- Decodes SAML messages
- Shows XML assertion content
- Displays signature verification
- Tracks redirect flow
Fiddler or Charles Proxy
- Intercept and inspect HTTPS traffic
- Modify requests on-the-fly
- Replay authentication flows
- Export HAR files for analysis
curl with --cookie-jar flag
# Save cookies from login
curl -c cookies.txt -X POST https://university.edu/login \
-d "username=user&password=pass"
# Use cookies for authenticated request
curl -b cookies.txt https://university.edu/protectedPlaywright trace viewer
// Record trace
await context.tracing.start({ screenshots: true, snapshots: true });
// Perform authentication
await context.tracing.stop({ path: 'trace.zip' });View trace: npx playwright show-trace trace.zip
Next Chapter: MCP Server Implementation - Build the authentication bypass server using these patterns.