Client API. The Codename One framework your app is built on: this runs on the device, not in a backend.

public interface RequestAuthorizer

Known subtypesRequestAuthorizer.Proactive, OidcRequestAuthorizer

Supplies the Authorization header of the requests an application sends to its own service, and renews it when the service refuses it.

An authorizer is given to one request with ConnectionRequest.setAuthorizer(RequestAuthorizer) or RequestBuilder.authorizer(RequestAuthorizer), or to every request under a base URL with NetworkManager.setAuthorizer(String, RequestAuthorizer):

NetworkManager.getInstance().setAuthorizer("https://api.example.com", authorizer);

OidcRequestAuthorizer is the implementation for a service that accepts OAuth 2.0 access tokens.

What happens to a request

  1. As the request is queued, getAuthorization(ConnectionRequest) is asked for a header value, which travels with the request. A request that already carries an Authorization header keeps its own: one the caller set always wins, and so does a default header of NetworkManager.
  2. If the service answers 401, nothing is delivered yet. The request is held and refreshAuthorization(ConnectionRequest, String) is asked for a new credential.
  3. If that succeeds the request is sent once more with the new header, and its answer – whatever it is, another 401 included – is delivered as usual. There is one renewal per request, so a service that keeps refusing cannot make this loop.
  4. If it fails, the request is sent again as it first was, and the service’s 401 goes through the request’s ordinary error handling exactly as it would have without an authorizer.

Code that waits for the request – NetworkManager.addToQueueAndWait(ConnectionRequest), the blocking methods of RequestBuilder, NetworkManager.addToQueueAsync(ConnectionRequest) – keeps waiting through all of it and sees only the final answer.

An authorizer that knows when its credential expires can skip the refused request altogether: see Proactive.

Threads

Every method of an authorizer is called on the event dispatch thread and on no other, so an implementation keeps its credential in plain fields and needs no lock. A network thread never calls one: it sends the header value that was put on the request, on the EDT, when the request was queued or released after a renewal. A request queued from another thread is passed to the EDT first, and so is a 401, which a network thread is the one to see.

The header is therefore the one current when the request was queued. If the credential is renewed while the request waits in the queue, the service refuses the old one and the request is sent again with the new one, as step 2 describes.

getAuthorization(ConnectionRequest) must answer from memory. It must not wait for another request: the EDT would wait on the queue it is filling. Renewing is therefore a separate step, which the authorizer starts and answers later.

Nested types

interface RequestAuthorizer.ProactiveAn authorizer that can tell, before a request is sent, that its credential is about to stop working, and renew it first.

Fields

public static final RequestAuthorizer NONEAn authorizer that never adds a header.

Methods

public abstract String getAuthorization(ConnectionRequest request)The value of the Authorization header for a request that is about to be sent, for example "Bearer eyJ...".
public abstract AsyncResource<Boolean> refreshAuthorization(ConnectionRequest request, String rejectedAuthorization)Called after the service answered 401 to a request that carried this authorizer’s header.

Field details

NONE

public static final RequestAuthorizer NONE
An authorizer that never adds a header. Set on a request, it keeps the default of NetworkManager.setAuthorizer(String, RequestAuthorizer) away from that one request – the request that fetches the token itself is the usual case.

Method details

getAuthorization

public abstract String getAuthorization(ConnectionRequest request)

The value of the Authorization header for a request that is about to be sent, for example "Bearer eyJ...".

Called on the event dispatch thread: when the request is queued, and again when it is sent a second time with a renewed credential. Answer from memory and do not block. The value is copied to the request; a redirect is sent the same one for as long as it stays under the base URL the authorizer was registered for.

Parameters

request ConnectionRequest
the request being queued

Returns

the header value, or null to send the request without one

refreshAuthorization

public abstract 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

request ConnectionRequest
the request that was refused
rejectedAuthorization String
the header value the service refused

Returns

a resource that completes with 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