Add examples for action token spi to explain how to create a token.

This commit is contained in:
Felix Peters 2018-03-19 21:32:50 +01:00 committed by Hynek Mlnařík
parent 218d2dd976
commit c143e2746b

View file

@ -35,7 +35,7 @@ In addition, an action token can contain any number of custom fields serializabl
When an action token is passed to a {project_name} endpoint
`_KEYCLOAK_ROOT_/auth/realms/master/login-actions/action-token` via `key` parameter, it is validated and a proper action
token handler is executed. The processing always takes place in a context of an authentication session, either a fresh
token handler is executed. *The processing always takes place in a context of an authentication session*, either a fresh
one or the action token service joins an existing authentication session (details are described below). The action token
handler can perform actions prescribed by the token (often it alters the authentication session) and results into an HTTP
response (e.g. it can continue in authentication or display an information/error page). These steps are detailed below.
@ -69,6 +69,68 @@ above), it can be serialized and signed as such using Keycloak's `JWSBuilder` cl
implemented in `serialize(session, realm, uriInfo)` method of `org.keycloak.authentication.actiontoken.DefaultActionToken`
and can be leveraged by implementors by using that class for tokens instead of plain `JsonWebToken`.
The following example shows the implementation of a simple action token. Note that the class must have a private constructor without any arguments.
This is necessary to deserialize the token class from JWT.
[source,java]
----
import org.keycloak.authentication.actiontoken.DefaultActionToken;
public class DemoActionToken extends DefaultActionToken {
public static final String TOKEN_TYPE = "my-demo-token";
public DemoActionToken(String userId, int absoluteExpirationInSecs, String compoundAuthenticationSessionId) {
super(userId, TOKEN_TYPE, absoluteExpirationInSecs, null, compoundAuthenticationSessionId);
}
private DemoActionToken() {
// Required to deserialize from JWT
super();
}
}
----
If the action token you are implementing contains any custom fields that should be serializabled to JSON fields, you
should consider implementing a descendant of `org.keycloak.representations.JsonWebToken` class that would implement
`org.keycloak.models.ActionTokenKeyModel` interface. In that case, you can take advantage of the existing
`org.keycloak.authentication.actiontoken.DefaultActionToken` class as it already satisfies both these conditions,
and either use it directly or implement its child, the fields of which can be annotated with appropriate Jackson
annotations, e.g. `com.fasterxml.jackson.annotation.JsonProperty` to serialize them to JSON.
The following example extends the `DemoActionToken` from the previous example with the field `demo-id`:
[source,java]
----
import com.fasterxml.jackson.annotation.JsonProperty;
import org.keycloak.authentication.actiontoken.DefaultActionToken;
public class DemoActionToken extends DefaultActionToken {
public static final String TOKEN_TYPE = "my-demo-token";
private static final String JSON_FIELD_DEMO_ID = "demo-id";
@JsonProperty(value = JSON_FIELD_DEMO_ID)
private String demoId;
public DemoActionToken(String userId, int absoluteExpirationInSecs, String compoundAuthenticationSessionId, String demoId) {
super(userId, TOKEN_TYPE, absoluteExpirationInSecs, null, compoundAuthenticationSessionId);
this.demoId = demoId;
}
private DemoActionToken() {
// you must have this private constructor for deserializer
}
public String getDemoId() {
return demoId;
}
}
----
==== Packaging Classes and Deployment
To plug your own action token and its handler, you need to implement few interfaces on server side:
@ -108,11 +170,4 @@ only method that needs to be implemented is `handleToken(token, context)` that p
Note that you have to register the custom `ActionTokenHandlerFactory` implementation as explained in the
<<_providers,Service Provider Interfaces>> section of this guide.
* If the action token you are implementing contains any custom fields that should be serializabled to JSON fields, you
should consider implementing a descendant of `org.keycloak.representations.JsonWebToken` class that would implement
`org.keycloak.models.ActionTokenKeyModel` interface. In that case, you can take advantage of the existing
`org.keycloak.authentication.actiontoken.DefaultActionToken` class as it already satisfies both these conditions,
and either use it directly or implement its child, the fields of which can be annotated with appropriate Jackson
annotations, e.g. `com.fasterxml.jackson.annotation.JsonProperty` to serialize them to JSON.