JWT Authentication
Secure JSON Web Token authentication for webMCP applications. Implement stateless authentication with scope-based authorization.
JWT Authentication Features
Comprehensive JWT implementation with advanced security features
Secure Token Signing
Sign JWT tokens with cryptographically secure algorithms
- HMAC-SHA256 (HS256) signing
- RSA-SHA256 (RS256) support
- ECDSA (ES256) for enhanced security
- Custom signing key rotation
Flexible Expiration
Configure token expiration and refresh strategies
- Configurable expiration times
- Automatic token refresh
- Sliding session windows
- Remember me functionality
Scope-Based Permissions
Fine-grained access control with JWT scopes
- Custom scope definitions
- Role-based access control
- Resource-level permissions
- Dynamic scope validation
JWT Token Structure
Understanding the structure of webMCP JWT tokens
Header
{
"alg": "HS256",
"typ": "JWT"
}Specifies the signing algorithm and token type
Payload
{
"sub": "user123",
"name": "John Doe",
"iat": 1640995200,
"exp": 1640998800,
"scopes": [
"webmcp:read",
"webmcp:write",
"user:profile"
]
}Contains user data, claims, and permissions
Signature
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)Cryptographic signature for verification
Implementation Examples
Practical examples for implementing JWT authentication
Basic JWT Authentication
Simple JWT token generation and validation
JavaScriptimport { WebMCPProcessor } from '@webmcp/core';
const processor = new WebMCPProcessor({
security: {
jwt: {
secret: process.env.JWT_SECRET,
expiresIn: '1h',
algorithm: 'HS256'
}
}
});
// Generate JWT token
const user = { id: 123, email: 'user@example.com' };
const token = processor.generateJWTToken(user, {
scopes: ['webmcp:read', 'webmcp:write'],
expiresIn: '24h'
});
// Validate JWT token
const validateToken = (token) => {
try {
const decoded = processor.verifyJWTToken(token);
console.log('Valid token:', decoded.payload);
return decoded;
} catch (error) {
console.error('Invalid token:', error.message);
return null;
}
};
// Use in middleware
app.use('/api', (req, res, next) => {
const token = req.headers.authorization?.replace('Bearer ', '');
const decoded = validateToken(token);
if (!decoded) {
return res.status(401).json({ error: 'Invalid token' });
}
req.user = decoded.payload;
next();
});Advanced JWT Configuration
Production-ready JWT setup with refresh tokens
JavaScriptconst jwtConfig = {
// Access token configuration
accessToken: {
secret: process.env.JWT_ACCESS_SECRET,
expiresIn: '15m', // Short-lived access tokens
algorithm: 'HS256',
issuer: 'webmcp-api',
audience: 'webmcp-client'
},
// Refresh token configuration
refreshToken: {
secret: process.env.JWT_REFRESH_SECRET,
expiresIn: '7d', // Long-lived refresh tokens
algorithm: 'HS256'
},
// Security options
security: {
clockTolerance: 30, // 30 seconds clock skew tolerance
maxAge: '1h', // Maximum token age regardless of exp
jti: true, // Include JWT ID for revocation
notBefore: true // Include nbf claim
}
};
const processor = new WebMCPProcessor({ security: { jwt: jwtConfig } });
// Generate token pair
const generateTokenPair = (user) => {
const accessToken = processor.generateJWTToken(user, {
type: 'access',
scopes: user.permissions,
expiresIn: jwtConfig.accessToken.expiresIn
});
const refreshToken = processor.generateJWTToken(user, {
type: 'refresh',
expiresIn: jwtConfig.refreshToken.expiresIn
});
return { accessToken, refreshToken };
};
// Refresh access token
const refreshAccessToken = (refreshToken) => {
try {
const decoded = processor.verifyJWTToken(refreshToken);
if (decoded.payload.type !== 'refresh') {
throw new Error('Invalid refresh token');
}
const user = {
id: decoded.payload.sub,
permissions: decoded.payload.scopes
};
return processor.generateJWTToken(user, {
type: 'access',
scopes: user.permissions,
expiresIn: jwtConfig.accessToken.expiresIn
});
} catch (error) {
throw new Error('Refresh token expired or invalid');
}
};Scope-Based Authorization
Implement fine-grained permissions with JWT scopes
JavaScript// Define scope hierarchy
const scopeHierarchy = {
'admin': ['user:*', 'webmcp:*', 'system:*'],
'user:write': ['user:read'],
'webmcp:write': ['webmcp:read'],
'webmcp:optimize': ['webmcp:read']
};
// Scope validation middleware
const requireScopes = (requiredScopes) => {
return (req, res, next) => {
const userScopes = req.user?.scopes || [];
const hasRequiredScopes = requiredScopes.every(required =>
userScopes.some(userScope => {
// Direct match
if (userScope === required) return true;
// Wildcard match
if (userScope.endsWith('*')) {
const base = userScope.slice(0, -1);
return required.startsWith(base);
}
// Hierarchy match
if (scopeHierarchy[userScope]) {
return scopeHierarchy[userScope].some(inherited =>
inherited === required ||
(inherited.endsWith('*') && required.startsWith(inherited.slice(0, -1)))
);
}
return false;
})
);
if (!hasRequiredScopes) {
return res.status(403).json({
error: 'Insufficient permissions',
required: requiredScopes,
provided: userScopes
});
}
next();
};
};
// Usage in routes
app.get('/api/user/profile',
requireScopes(['user:read']),
(req, res) => {
res.json({ profile: getUserProfile(req.user.sub) });
}
);
app.post('/api/webmcp/optimize',
requireScopes(['webmcp:optimize']),
(req, res) => {
// Process optimization request
const result = processor.optimize(req.body);
res.json(result);
}
);
app.delete('/api/admin/users/:id',
requireScopes(['admin']),
(req, res) => {
// Admin-only operation
deleteUser(req.params.id);
res.json({ success: true });
}
);Python JWT Implementation
JWT authentication in Python applications
Pythonfrom webmcp_core import WebMCPProcessor, JWTConfig
from datetime import datetime, timedelta
import jwt
import os
# Configure JWT
jwt_config = JWTConfig(
secret=os.getenv('JWT_SECRET'),
algorithm='HS256',
expires_in=3600, # 1 hour
issuer='webmcp-api',
audience='webmcp-client'
)
processor = WebMCPProcessor(security={'jwt': jwt_config})
class JWTAuth:
def __init__(self, processor):
self.processor = processor
def generate_token(self, user_id, scopes=None, expires_in=None):
payload = {
'sub': str(user_id),
'iat': datetime.utcnow(),
'exp': datetime.utcnow() + timedelta(seconds=expires_in or 3600),
'iss': 'webmcp-api',
'aud': 'webmcp-client'
}
if scopes:
payload['scopes'] = scopes
return self.processor.generate_jwt_token(payload)
def verify_token(self, token):
try:
return self.processor.verify_jwt_token(token)
except jwt.ExpiredSignatureError:
raise ValueError('Token has expired')
except jwt.InvalidTokenError:
raise ValueError('Invalid token')
def require_scopes(self, required_scopes):
def decorator(func):
def wrapper(*args, **kwargs):
# Extract token from request context
token = get_current_token() # Implementation specific
try:
decoded = self.verify_token(token)
user_scopes = decoded.get('scopes', [])
if not all(scope in user_scopes for scope in required_scopes):
raise PermissionError('Insufficient scopes')
return func(*args, **kwargs)
except (ValueError, PermissionError) as e:
raise HTTPException(status_code=403, detail=str(e))
return wrapper
return decorator
# Usage example
auth = JWTAuth(processor)
@app.route('/api/login', methods=['POST'])
def login():
# Authenticate user
user = authenticate_user(request.json['email'], request.json['password'])
if user:
token = auth.generate_token(
user.id,
scopes=['user:read', 'webmcp:read'],
expires_in=86400 # 24 hours
)
return {'token': token, 'user': user.to_dict()}
return {'error': 'Invalid credentials'}, 401
@auth.require_scopes(['webmcp:write'])
@app.route('/api/webmcp/process', methods=['POST'])
def process_webmcp():
result = processor.parse_webmcp(request.json['html'])
return result.to_dict()Security Best Practices
Essential security practices for JWT implementation
Token Security
Use Strong Secrets
Use cryptographically secure secrets for JWT signing
Short Access Token Expiry
Keep access tokens short-lived to limit exposure
Algorithm Verification
Always verify the JWT algorithm to prevent attacks
Token Storage
Secure Client Storage
Store tokens securely on the client side
Token Transmission
Always transmit tokens over secure connections
Token Revocation
Implement token revocation for compromised tokens
Implementation Security
Validate All Claims
Validate all JWT claims including iss, aud, exp
Rate Limiting
Implement rate limiting for token endpoints
Audit Logging
Log all authentication and authorization events
Troubleshooting Guide
Common JWT issues and their solutions
Token Expired
Symptoms
- 401 Unauthorized errors
- Automatic logout
- API requests failing
Solutions
- Implement automatic token refresh
- Check system clock synchronization
- Adjust token expiration times
- Implement sliding sessions
Invalid Signature
Symptoms
- JWT verification failures
- Signature mismatch errors
Solutions
- Verify JWT secret configuration
- Check algorithm consistency
- Ensure proper key rotation
- Validate token format
Insufficient Scopes
Symptoms
- 403 Forbidden errors
- Permission denied messages
Solutions
- Review user role assignments
- Check scope hierarchy configuration
- Verify token includes required scopes
- Update user permissions
Implement Secure Authentication
Start using JWT authentication to secure your webMCP applications with stateless authentication