Okta Certified Developer study materials
Okta Certified Developer study resources

Okta Certified Developer: Authentication and Authorization

Okta Certified Developer · Work through your exam, one topic at a time.

All guide sections

Authentication and Authorization

This domain checks that you can pick the right OIDC/OAuth 2.0 flow, choose between the org and a custom authorization server, validate tokens correctly, and reason about policies, scopes and claims.

Flows

  • Authorization Code + PKCE (code_challenge_method=S256) for SPAs, native and mobile apps, and server-side web; confidential clients add a client secret. Okta requires PKCE for SPA app types.
  • Client Credentials for machine-to-machine: access token only - no ID token, no refresh token.
  • Device Authorization for input-constrained devices.
  • Interaction Code for embedded sign-in with Identity Engine via the Sign-In Widget or SDKs.
  • Implicit and Resource Owner Password are legacy; do not propose them.

Which authorization server

  • Org AS (/oauth2/v1/authorize) issues tokens only for Okta's own APIs - not for your custom audience.
  • Custom AS (/oauth2/{id}/v1/..., including default) is required for your own APIs. Its access policies and rules decide which clients and users may obtain tokens, which grant types apply, token lifetimes, and whether claims are included.

Tokens and claims

  • ID token: JWT with iss (AS issuer), aud (client_id), sub, exp, iat, nonce, auth_time. Validate the signature via the /v1/keys JWKS, then iss, aud, exp and nonce.
  • Access token: what the resource server checks. It may be opaque or a JWT; if a JWT, validate locally via JWKS, otherwise call /v1/introspect.
  • Refresh token: on a custom AS it requires the offline_access scope, and rotation is configured on the AS.
  • Claims are driven by scope plus expression-based mappings such as user.profile.department, or a groups claim filtered by a group-name regex.

Worked example

An SPA's /token call returns invalid_grant. Two likely causes: the code_verifier does not hash (S256) to the original code_challenge, or the code was already redeemed. The exchange happens once, within the code lifetime, and the redirect_uri must be byte-identical to the value sent at /authorize.

Traps

Wildcards or fragments in redirect_uri (https required except localhost, and match is exact); skipping state or nonce validation; comparing aud against the API audience in an ID token; and using the org AS for a custom API, which fails policy evaluation.