Client API. The Codename One framework your app is built on: this runs on the device, not in a backend.
public final class OidcRequestAuthorizer
- Object
- OidcRequestAuthorizer
ImplementsRequestAuthorizer, RequestAuthorizer.Proactive
Sends an OidcClient’s access token with the application’s requests, and renews it with the
refresh token when the service refuses it.
OidcRequestAuthorizer authorizer = new OidcRequestAuthorizer(client);
authorizer.install("https://api.example.com");
authorizer.load(); // a session saved by an earlier run, if there is one
From then on every request under that base URL carries Authorization: Bearer ...,
generated @RestClient clients included. The authorizer follows its client: tokens obtained
by OidcClient.authorize(), OidcClient.refresh(String) or the device grant are picked up
as they arrive, and OidcClient.clearStoredTokens() drops them.
When the service answers 401
The request is held and the refresh token is exchanged for a new set – once, however many
requests were refused together; they all wait for the same exchange. Each is then sent again
with the new access token. See RequestAuthorizer for what the caller of a request sees.
When the authorization server returns a permanent refresh error, the session is over: the tokens
are dropped from memory and from the TokenStore, the held requests deliver their 401,
and every SignInRequiredListener is told so the application can show its sign-in screen.
Transport failures, malformed responses, and the provider’s server_error or
temporarily_unavailable errors keep the tokens: nothing has said they are bad.
Before the token expires
A refusal is the fallback, not the way a token is normally renewed. When a request is
queued and the access token is within setRefreshLeeway(int) of its expiry – sixty
seconds unless set – the refresh token is exchanged first and the request is kept out
of the queue until the exchange is done. It is then sent once, with the new token.
Requests queued in the meantime wait for the same exchange.
Nothing blocks for this: the request has simply not been handed to a network thread
yet. Code that waits for it – addToQueueAndWait, the blocking methods of
RequestBuilder – returns the one final answer.
If that exchange is refused the session ends as described above, and the request goes
out with no token for the service to answer 401. If it fails without an answer the
request is sent with the token it has, which may still be good, and no exchange is tried
ahead of time for the next few seconds.
A token whose response carried no expires_in has no known expiry, and is renewed only
when the service refuses it.
Threads
Everything an authorizer holds – the tokens, the exchange in progress, the listeners –
belongs to the event dispatch thread and is read and changed nowhere else. Nothing here
is locked. A network thread never calls an authorizer: it sends the header the EDT put
on the request when the request was queued. Tokens that arrive on a network thread, and
a 401 seen there, are passed to the EDT before the authorizer hears of them.
Call this class on the EDT. The methods that read or change its state can also be called from another thread, and then wait for the EDT to do the work – so not from a thread the EDT is itself waiting for.
Nested types
interface OidcRequestAuthorizer.SignInRequiredListener | Told when the user has to sign in again. |
Constructors
public OidcRequestAuthorizer(OidcClient client) | An authorizer for the tokens of client. |
Methods
Inherited nested types
Inherited fields
Inherited methods
Constructor details
OidcRequestAuthorizer
public OidcRequestAuthorizer(OidcClient client)An authorizer for the tokens of client.
A client has one authorizer: creating a second one for the same client takes its place.
Parameters
clientOidcClient- a configured client
Method details
install
public OidcRequestAuthorizer install(String baseUrl)NetworkManager.setAuthorizer(String, RequestAuthorizer), whose matching rules apply.Parameters
baseUrlString- the base URL of the application’s service
Returns
load
public AsyncResource<OidcTokens> load()SecureStorageTokenStore that requires biometrics, this is the one
moment the user is prompted.Returns
getTokens
public OidcTokens getTokens()Returns
setTokens
public void setTokens(OidcTokens tokens)Parameters
tokensOidcTokens- the tokens, or null for none
isSignedIn
public boolean isSignedIn()signOut
public AsyncResource<Boolean> signOut()Drops the tokens from memory and from the client’s TokenStore. Requests go out
without a header from then on. This doesn’t tell the server; call
OidcClient.revoke(String) with the refresh token first for that.
A renewal in progress is abandoned: whatever it comes back with is dropped, and the requests waiting for it go out with no token.
Returns
addSignInRequiredListener
public void addSignInRequiredListener(OidcRequestAuthorizer.SignInRequiredListener listener)removeSignInRequiredListener
public void removeSignInRequiredListener(OidcRequestAuthorizer.SignInRequiredListener listener)setRefreshLeeway
public OidcRequestAuthorizer setRefreshLeeway(int seconds)401 as the only trigger.Parameters
secondsint- the leeway in seconds
Returns
getRefreshLeeway
public int getRefreshLeeway()setRefreshLeeway(int).getAuthorization
public String getAuthorization(ConnectionRequest request)Parameters
requestConnectionRequest- the request being queued
Returns
prepareAuthorization
public AsyncResource<Boolean> prepareAuthorization(ConnectionRequest request)Parameters
requestConnectionRequest- the request being queued
Returns
RequestAuthorizer.getAuthorization(ConnectionRequest) answers
thenrefreshAuthorization
public AsyncResource<Boolean> refreshAuthorization(ConnectionRequest request, String rejectedAuthorization)Called after the service answered 401 to a request that carried this authorizer’s
header. Called on the event dispatch thread, at most once per request.
Several requests can be refused at the same moment. An implementation should renew its
credential once and give every one of them the same answer, and should recognize a
rejectedAuthorization that is no longer the current one: that request was sent before
an earlier renewal finished, and only needs sending again.
Parameters
requestConnectionRequest- the request that was refused
rejectedAuthorizationString- the header value the service refused
Returns
true once a different credential is ready, and with
false or an error when there is none to be had. Null means the same as false