Products Downloads


French version


 

JWT token revocation by the resource server is an additional security element.
Any token which is no longer needed despite still being valid must be revoked. This prevents users from maliciously identifying themselves to a service.
The revocation operation is performed via an explicit request to a dedicated web API.

Adelia Studio offers two token revocation implementations:

  • Simple implementation for a single resource server.
  • Distributed implementation (several resource servers and/or third-party applications need to be informed of revoked tokens). This implementation is based on the Nats/Jetstream open source message broker.


Configuring revocation management

Revocation management is not enabled by default. To make it operational, a JwtRevokeConfiguration-type bean needs to be declared in the Beans.xml file.


Simple Mode
jwtRevokeConfiguration
<bean id="jwtTokensRevocation" class="com.hardis.adelia.webservice.JwtRevokeConfiguration" init-method="loadTokensMap" destroy-method="saveTokensMap" />
      
or 

<bean id="jwtTokensRevocation" class="com.hardis.adelia.webservice.JwtRevokeConfiguration" init-method="loadTokensMap" destroy-method="saveTokensMap">
      <property name="jwtClaimId"               value="???"/> <!-- default value: jti -->
      <property name="jwtPurgeFrequencyTime"    value="???"/> <!-- default value: 3600 -->        
</bean>


  • jwtClaimId: List of claim names able to identify the JWT. Default value: "jti". This information is mandatory: when revocation management is enabled, token validation - identified by its ID - is dependent on it not being revoked.

    Note:

    The token is identified by the first claim name in the valid list for the token. If the token does not have a valid claim for at least one of the names designated by the jwtClaimId property, token validation will fail; a 401 error will therefore be returned by the server.
  • jwtPurgeFrequencyTime: Purge frequency, in seconds, of the revoked token table. Default value: 3600. To be adapted according to the token validity period.


Distributed mode

In this mode, each revocation request issues a message in the ${jwtNatsSubject} subject of the ${jwtNatsStreamName} stream. The messages are kept in the stream for the period defined by ${jwtNatsStreamMaxAge}.
The message is a string in UTF-8 format comprising four fields delimited by the ; character. → Example: <JwtId>;<RevokedBy>;<RevocationRequestDate>;<TokenExpirationDate>

  • <JwtId>: String> → Token Id
  • <RevokedBy>: String> → Name of user initiating the revocation ( token 'sub' used during revocation)
  • <RevocationRequestDate>: String; ISO-8601 → Revocation request date.
  • <TokenExpirationDate>: Length → Scheduled token expiry date (unix time).
jwtRevokeConfiguration - Example: distributed implementation
<bean id="jwtTokensRevocation" class="com.hardis.adelia.webservice.JwtRevokeConfiguration" init-method="loadTokensMap" destroy-method="saveTokensMap"> 
   <property name="jwtClaimId" value="???"/> <!-- default value: jti -->
   <property name="jwtNatsServers" value="localhost:4222"/> <!-- if one or more servers are defined, shared mode is enabled provided there is a successful connection to one of the servers -->
   <property name="jwtNatsStreamName" value="ADELIASTREAM"/> <!-- Dedicated stream name; default: "ADELIASTREAM" -->
   <property name="jwtNatsSubject" value="streaming.adelia.internal.jwt.revoke"/> <!-- Subject name; default: "streaming.adelia.internal.jwt.revoke" -->
   <property name="jwtNatsStreamMaxAge" value="12"/> <!--in hours, maximum age of messages in the stream - value to be set in relation to the token lifespan; default: "24"-->
   
   <!-- Nats authentication : nkey -->
   <property name="jwtNatsAuthNKeySeed" value="CRYPT(00D133D32D285115D308A5E89F9CEA80D227FDB3304CBD18AD596D09AA40359D7F3DA0F74CCDE20B8A6BD53687A2584851712091A26207A7F7D790DD719753E7D7)"/>
</bean>
  • jwtClaimId: List of claim names able to identify the JWT. Default value: "jti". This information is mandatory: when revocation management is enabled, token validation - identified by its ID - is dependent on it not being revoked.

    Note:

    The token is identified by the first claim name in the valid list for the token. If the token does not have a valid claim for at least one of the names designated by the jwtClaimId property, token validation will fail; a 401 error will therefore be returned by the server.
  • jwtNatsServers: Name of Nats server or names of Nats servers (separated by a ; → example: srvnats1:4222;srvnats2:4222).
  • jwtNatsStreamName: Name of dedicated stream [default: ADELIA_JWT_TOKEN_STREAM].
  • jwtNatsSubject: Name of subject used to revoke tokens [default: streaming.adelia.internal.jwt.revoke].
  • jwtNatsStreamMaxAge: Maximum age of messages in the dedicated stream. This age must be greater than the token lifespan so that a new client/subscriber is aware of all the revoked tokens that are possibly active.


Nats server authentication

  • User/Password
    jwtNatsAuthUser: User's name
    jwtNatsAuthPwd: Password. Use the Adelia runtime "java EncryptPassword" command to encrypt the password and specify the password in brackets, prefixed by "CRYPT".
     → Example:

    <property name="jwtNatsAuthUser" value="bob"/><property name="jwtNatsAuthPwd" value="s3cr3t"/>
    <property name="jwtNatsAuthUser" value="bob"/>
    <property name="jwtNatsAuthPwd" value="CRYPT(0040B783FDB007E032)"/>
  • Token
    jwtNatsAuthToken: To encrypt the token, use the "java EncryptPassword" Adelia runtime command and specify the password in brackets prefixed by "CRYPT".
     → examples:
    <property name="jwtNatsAuthToken" value="s3cr3t"/>
    <property name="jwtNatsAuthToken" value="CRYPT(0040B783FDB007E032)"/>
  • Nkey
    jwtNatsAuthNKeySeed: private key. To encrypt the key, use the "java EncryptPassword" Adelia runtime command and specify the password in brackets prefixed by "CRYPT".
     → examples:
    <property name="jwtNatsAuthNKeySeed" value="SUAFGCEVJB6DTYFPEQIC4DSLGBRSD75BMQPO2HS6SX4FNPVZDTHMQYYN24"/>
    <property name="jwtNatsAuthNKeySeed" value="CRYPT(00D133D32D285115D308A5E89F9CEA80D227FDB3304CBD18AD596D09AA40359D7F3DA0F74CCDE20B8A6BD53687A2584851712091A26207A7F7D790DD719753E7D7)"/>
  • Credentials file

    jwtNatsAuthCredsFile: location of the file containing the authentication information. See https://docs.nats.io/using-nats/developer/connecting/creds

     → example:<property name="jwtNatsAuthCredsFile" value="nats.creds"/>


Who can revoke a token?

The token can only be revoked by a request authenticated by the same token.


Revoked token table persistence

The revoked token table remains after the resource server has been restarted.


Revoked token table purge

The revoked token table is purged at a specific frequency (every hour by default. See jwtPurgeFrequencyTime). Revoked tokens which have expired are purged.

↑ Top of page


Web APIs

Objective
API access point
HTTP verb
Response
Status 

Revocation


/<ContextPath>/<CXF_url-pattern>/tokens/revocation

@DELETE 

Media-type: text/plain
Values: true | false 

200 
401
404 

Is the jwtId token revoked?


/<ContextPath>/<CXF_url-pattern>/tokens/revocation/{jwtId}


@GET 

Media-type: text/plain
Values: true | false


200
401
404

List of revoked tokens

/<ContextPath>/<CXF_url-pattern>/tokens/revocation/list


@GET 

Media-type: application/json

[ { "jwtId": "TokenId__FE706DC72E90060E9E88FB887ACB72E1_25_1619685311434", "revokedBy": "userName", "revocationRequestDate": "2021-04-29T08:35Z", "expirationDate": 1619688911 }, { "jwtId": "TokenId__FE706DC72E90060E9E88FB887ACB72E1_28_1619685265807", "revokedBy": "userName", "revocationRequestDate": "2021-04-29T08:35Z", "expirationDate": 1619688865 } ]

200
401
404



HTTP Code:

  • If the operation is successful: HTTP Code = 200

  • If the operation fails because the revocation request is not authorized: HTTP Code = 401

  • If the JwtRevokeConfiguration bean is not declared (= revocation not active) or if the requested token is not found: HTTP Code = 404.


Example of token revocation - Adelia code
EXECUTE_HTTP *URL('http://mysite/mawebapp/ws/tokens/revocation') *OPTIONS('--request DELETE --header Accept: text/plain --header Authorization:JWT <jwt_token>') *RESPONSE(VarRetCode) *HTTP_CODE(VarHttpCode)
Note: "<jwt_token>" corresponds to the token value

Top of page


  • Aucune étiquette