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
- As the request is queued,
getAuthorization(ConnectionRequest)is asked for a header value, which travels with the request. A request that already carries anAuthorizationheader keeps its own: one the caller set always wins, and so does a default header ofNetworkManager. - If the service answers
401, nothing is delivered yet. The request is held andrefreshAuthorization(ConnectionRequest, String)is asked for a new credential. - If that succeeds the request is sent once more with the new header, and its answer –
whatever it is, another
401included – is delivered as usual. There is one renewal per request, so a service that keeps refusing cannot make this loop. - If it fails, the request is sent again as it first was, and the service’s
401goes 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.Proactive | An 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 NONE | An 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 NONENetworkManager.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
requestConnectionRequest- the request being queued
Returns
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
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