Next Practical Step
Build a token sampler with JSON extraction and a single protected GET; validate with one thread before scaling.
Load test JWT, OAuth2, and SSO APIs in JMeter: token endpoints, Bearer headers, refresh flows, Cookie Manager, CSV users, and fixing 401 failures.
Most modern APIs and portals require authentication. Under load you must obtain credentials per virtual user, keep tokens fresh, and attach them on every protected call without hard-coding secrets. This guide covers JWT bearer flows, OAuth-style token endpoints, cookie-based SSO patterns, and failure modes using core JMeter HTTP elements documented in the component reference, functions, and best practices.
JMeter does not ship a dedicated โOAuth sampler.โ You model auth as ordinary HTTP Request steps plus headers, cookies, and extractors. That matches how production clients call token and resource servers.
| Pattern | What JMeter must do |
|---|---|
| API key | Static or property-driven header on every call |
| Bearer JWT | Login/token call, extract access token, set Authorization |
| OAuth2 client credentials | POST to token URL with client id/secret, extract token |
| OAuth2 password / ROPC (if your IdP still allows it) | POST username/password, extract token |
| Authorization code + browser SSO | Often needs recording, cookies, and correlation of state/CSRF (see recorder) |
| Session cookie SSO | Cookie Manager + login form POST; optional CSRF extract |
For pure HTTP APIs, start from the API load testing plan shape, then add an auth step in front of business calls.
Test Planโโโ User Defined Variables / properties for host, client_idโโโ HTTP Request Defaults (protocol, server, port)โโโ HTTP Header Manager (Content-Type, Accept)โโโ HTTP Cookie Manager (if browser/SSO cookies matter)โโโ Thread Group โโโ Once Only Controller (or first sampler) โ โโโ Token / Login HTTP Request โ โโโ JSON or Regex Extractor โ accessToken โ โโโ Response Assertion (2xx) โโโ HTTP Header Manager (Authorization: Bearer \${accessToken}) โ or header on each protected sampler โโโ Business HTTP Requests + assertionsUse a Once Only Controller so each thread logs in once, then loops API work. That models long-lived sessions better than re-authenticating every iteration (unless your scenario requires re-login).
Typical OAuth2 token endpoint (fields vary by IdP):
/oauth/token or /realms/.../protocol/openid-connect/tokengrant_type, client_id, client_secret, optional scope, username, passwordExample form-style body (illustrative):
grant_type=client_credentials&client_id=\${__P(clientId,)}&client_secret=\${__P(clientSecret,)}&scope=api.readSet Content-Type: application/x-www-form-urlencoded on a Header Manager scoped to this sampler when using form encoding. For JSON token APIs, use Body Data and application/json.
Prefer a JSON Extractor (or JMESPath-style extraction when available) when the body is:
{ "access_token": "eyJhbGciOi...", "expires_in": 3600, "token_type": "Bearer"}accessToken$.access_token (confirm against your response)TOKEN_NOT_FOUND so failures are visibleIf the token is only available as free text, use a Regular Expression Extractor with a capture group and template $1$. The site Regex Extractor Builder helps draft fields from a sample body (browser-local).
Add an HTTP Header Manager:
| Name | Value |
|---|---|
| Authorization | Bearer \${accessToken} |
Scope:
Header Manager children of a sampler override or supplement higher-level managers depending on how you structure the tree; keep the model simple: one post-login Header Manager for the protected section.
Without assertions, failed logins produce hours of 401 noise. Add a Response Assertion on the token sampler for response code 200 (or whatever your IdP returns) and optionally a substring check that access_token appears.
Official best practices show multi-user login via CSV Data Set Config:
user,pass (or client_id,client_secret per tenant).\${user} / \${pass} on the token or login sampler.Never use one shared password for thousands of threads if the system under test enforces concurrent session limits or rate-limits that user.
JWTs expire (expires_in). Options under load:
\${__time} / script logic).refresh_token: second HTTP Request + extractor updating accessToken.Keep refresh logic thread-local via variables. Do not put per-user access tokens in properties unless you intentionally share one token across threads (usually unrealistic and unsafe).
Variables are thread-local; properties are JVM-global (functions guide).
Browser SSO often sets session cookies after SAML/OIDC redirects.
state, nonce, and form fields (correlation guide).JMeter does not execute browser JavaScript. If login requires heavy client-side crypto or WebAuthn-only paths, you may need a different approach (pre-minted tokens, test IdP, or a real browser tool for that step only).
For HTTP Basic, the HTTP Authorization Manager can supply credentials for a base URL. For Bearer JWT, Header Manager is the usual path. See also advanced web test plan notes on where to place managers.
| Property | Example use |
|---|---|
tokenUrl / host | Staging vs prod IdP |
clientId / clientSecret | CI secrets |
threads / rampup | Load profile |
jmeter -n -t auth-api.jmx \ -Jhost=api.staging.example.com \ -JclientId="$CLIENT_ID" \ -JclientSecret="$CLIENT_SECRET" \ -Jthreads=50 \ -l results.jtl -e -o report/Plan fields use \${__P(host,)} and similar (best practices).
Measure:
If the IdP is shared, include it in capacity discussions: load tests can DDoS your own auth tier.
| Symptom | Likely cause | Fix |
|---|---|---|
| All 401 after first success in recording | Token/cookie not correlated | Extractor + Cookie Manager |
\${accessToken} literal in header | Extractor failed | Default value, Tree view, JSON path |
| Works for 1 user, fails at scale | IdP rate limit, same user CSV | Unique users; throttle auth |
| Intermittent 401 mid-test | Expiry | Refresh or re-login |
| SSL errors to IdP | Trust store / SNI | JVM trust; HTTP Request TLS settings |
| Secrets leaked in jmx/jtl | Body saved | Minimize saveservice; property secrets |
No. Model token and resource calls with HTTP Request, Header Manager, Cookie Manager, and extractors.
Extract access_token into a variable, then set header Authorization to Bearer \${accessToken}.
Usually no. Shared tokens hide per-user cache and session behaviour and can hit concurrent-use limits. Prefer CSV users or client-credentials per tenant as your scenario requires.
Token expiry, IdP throttling, wrong cookie scope, or extractors failing when error bodies replace JSON tokens. Assert on the login sampler and watch error % by label on the dashboard.
You can record HTTP redirects and posts, but complex browser-only steps may not replay. Many teams inject API tokens for the load phase and test full SSO separately.
In CI secrets or local env, passed via -J into \${__P(...)}, not hard-coded in the plan file.
On this page