Client API. The Codename One framework your app is built on: this runs on the device, not in a backend.
public final class OidcClient
- Object
- OidcClient
Modern OpenID Connect / OAuth 2.0 client. Built around the authorization-code flow with PKCE (RFC 7636) and the system browser. Use it as the foundation for all new sign-in integrations:
OidcClient.discover("https://accounts.google.com").ready(new SuccessCallback<OidcClient>() {
public void onSucess(OidcClient client) {
client.setClientId("YOUR_CLIENT_ID")
.setRedirectUri("com.example.app:/oauth2redirect")
.setScopes("openid", "email", "profile");
client.authorize().ready(new SuccessCallback<OidcTokens>() {
public void onSucess(OidcTokens tokens) {
// use tokens.getAccessToken() / tokens.getIdToken()
}
});
}
});
What this gives you that Oauth2 does not
- Discovery via
.well-known/openid-configurationso you only configure the issuer URL, not five separate endpoints - PKCE S256 on every flow (mandatory; many providers now require it)
- System-browser sign-in via
SystemBrowser(the previous class used an in-app WebView that modern IdPs reject) - Refresh-token flow surfaced as a first-class method
- ID-token claim decoding via
OidcTokens.getClaim(String) - Pluggable
TokenStorepersistence - Nonce + state verification on every authorization round-trip
What is checked before tokens are handed over
- The authorization response: its
state, and the issuer it names. A response that names another issuer than this client’s is refused, and so is one that names none when the provider’s discovery document says it always does (RFC 9207). That is what stops a response from one provider being taken for another’s. - The ID token’s claims:
issis the provider,audis this client,exphas not passed,nonceis the one the request carried, andat_hash, when the token has one, is the hash of the access token it came with. - The ID token’s signature, against the provider’s keys. The keys are fetched from the
configuration’s
jwks_urionce and kept, and fetched again when a token names a key that is not among them.RS256,RS384,RS512,ES256andES384are accepted; an unsigned token, or one signed with the client secret, is not.
A token that fails any of this is not stored and not returned: the resource fails
with OidcException.INVALID_ID_TOKEN, OidcException.NONCE_MISMATCH or
OidcException.ISSUER_MISMATCH. That includes a signature this platform has no way
to check. Nothing is skipped quietly – see setVerifyIdTokenSignature(boolean) for
the one switch there is, and what turning it off gives up.
Things this class deliberately does NOT do
- Implicit and hybrid flows. Use the lower-level
ConnectionRequestAPIs if you need those.
A device without a browser or a keyboard
requestDeviceAuthorization() and pollDeviceToken(OidcDeviceAuthorization)
run the device authorization grant (RFC 8628): the device shows a short
code, the user approves it on a phone or a computer, and the device
receives its tokens.
Using the tokens
OidcRequestAuthorizer attaches the access token to the application’s
requests and renews it with the refresh token when the service refuses it.
Methods
Inherited methods
Method details
create
public static OidcClient create(OidcConfiguration configuration)OidcConfiguration. Use
discover(String) when you’d rather pull the endpoints from the
provider’s .well-known/openid-configuration document.discover
public static AsyncResource<OidcClient> discover(String issuer)Fetches <issuer>/.well-known/openid-configuration and resolves with
an OidcClient pre-populated with the discovered endpoints. The
returned client still needs clientId, redirectUri and scopes
before authorize() will work.
Trailing slashes are removed when building the discovery request URL. The
metadata’s issuer must still exactly match the supplied issuer, including
its trailing slashes, before any discovered endpoints are accepted.
getConfiguration
public OidcConfiguration getConfiguration()setClientId
public OidcClient setClientId(String clientId)setClientSecret
public OidcClient setClientSecret(String clientSecret)setRedirectUri
public OidcClient setRedirectUri(String redirectUri)setScopes
public OidcClient setScopes(String... scopes)setScopes
public OidcClient setScopes(List<String> scopes)setAuthorizationParameters
public OidcClient setAuthorizationParameters(String... kv)name=value parameters appended to the authorization-endpoint
URL. Use for provider-specific options like Google’s prompt=consent
or Apple’s response_mode=form_post. Values are URL-encoded.setTokenParameters
public OidcClient setTokenParameters(String... kv)name=value parameters sent as form data on every token-endpoint
POST.setTokenStore
public OidcClient setTokenStore(TokenStore store)TokenStore.DefaultStorageTokenStore.setStoreKey
public OidcClient setStoreKey(String key)setEnforceNonce
public OidcClient setEnforceNonce(boolean enforce)false skips the nonce claim check on the returned ID token. Only
disable when you have a very good reason (e.g. provider known not to
echo the nonce); the default is to enforce.setVerifyIdTokenSignature
public OidcClient setVerifyIdTokenSignature(boolean verify)Whether an ID token’s signature is verified against the provider’s keys before the token is accepted. True unless set.
With it on, a token whose signature cannot be checked is refused – because it does
not verify, because the configuration names no jwks_uri, or because the platform
the app is running on cannot verify a signature of that algorithm. The last one is
the reason this switch exists: turn it off for a provider whose ID tokens cannot be
verified on a platform you ship to, and for no other reason.
With it off, the claims are still checked, but they are only as good as the TLS connection to the token endpoint. Do not make a decision on your server from an ID token the app forwards: verify it there.
setIdTokenClockSkew
public OidcClient setIdTokenClockSkew(int seconds)exp is
checked. Five minutes unless set: phones are set by hand more often than servers.setResponseMode
public OidcClient setResponseMode(String mode)response_mode parameter sent on the authorization URL
(e.g. "form_post" for Apple Sign-In with the web fallback).authorize
public AsyncResource<OidcTokens> authorize()AsyncResource completes with
the token set or errors with OidcException (e.g. USER_CANCELLED,
STATE_MISMATCH).refresh
public AsyncResource<OidcTokens> refresh(String refreshToken)Exchanges a stored refresh token for a fresh access token. Pass the
value returned from OidcTokens.getRefreshToken() on a previous flow.
The stored session supplies the original subject for any refreshed ID token.
A refresh response cannot change that subject. The new tokens are persisted
via the current TokenStore.
Cancelling the returned resource before it completes drops the answer: nothing is
stored and no OidcRequestAuthorizer is given the new tokens.
loadStoredTokens
public AsyncResource<OidcTokens> loadStoredTokens()null). Combine
with refreshIfExpired(int) to silently bring the session back to
life on app launch.refreshIfExpired
public AsyncResource<OidcTokens> refreshIfExpired(int leewaySeconds)leewaySeconds of expiring,
runs a refresh and saves the new tokens. Completes with null when
nothing is stored or when the stored token has no refresh token and
has already expired.revoke
public AsyncResource<Boolean> revoke(String token)revocation_endpoint.
A refused request reports the OAuth error, or a transport error when the
non-success HTTP response contains no OAuth error.clearStoredTokens
public AsyncResource<Boolean> clearStoredTokens()revoke(String) if you want a
proper sign-out. The returned resource completes after earlier saves and
this clear finish, so a delayed save cannot restore the cleared session.requestDeviceAuthorization
public AsyncResource<OidcDeviceAuthorization> requestDeviceAuthorization()Starts the device authorization grant (RFC 8628), for a device with no browser or no practical way to type: a television, a watch, a kiosk, a command line.
The answer holds a short code. Show it with the verification address; the user opens
that address on another device, signs in and types the code. Meanwhile pass the answer
to pollDeviceToken(OidcDeviceAuthorization), which completes once they have.
Needs a client id, the scopes, and a provider whose configuration names a
device_authorization_endpoint. No redirect URI is involved.
Returns
OidcException carrying the
server’s error codeThrows
IllegalStateException- when the client id is missing, or the provider does not offer the grant
pollDeviceToken
public AsyncResource<OidcTokens> pollDeviceToken(OidcDeviceAuthorization authorization)Waits for the user to approve a device, by asking the token endpoint at the pace the server set.
The wait is a timer, not a thread: each request is queued when the previous answer’s
interval has passed. The interval starts at
OidcDeviceAuthorization.getInterval() and grows by five seconds every time the
server answers slow_down, and doubles after a request that failed to reach the server
at all.
The resource completes with the tokens, which are saved to the TokenStore the way
authorize() saves them. It fails with an OidcException whose code is
OidcException.ACCESS_DENIED when the user refused, OidcException.EXPIRED_TOKEN
when the codes ran out – by the server’s word or by the clock – or whatever other
code the server sent. Cancelling the resource stops the polling.
Parameters
authorizationOidcDeviceAuthorization- the answer of
requestDeviceAuthorization()