Grzegorz Grzybek created ARTEMIS-5983:
-----------------------------------------

             Summary: Support credentials which may expire
                 Key: ARTEMIS-5983
                 URL: https://issues.apache.org/jira/browse/ARTEMIS-5983
             Project: Artemis
          Issue Type: New Feature
          Components: JAAS
            Reporter: Grzegorz Grzybek


ARTEMIS-5200 is about adding {{OIDCLoginModule}} which authenticates incoming 
connections using JWT credentials.

In AMQP, just as passwords are sent using SASL PLAIN (or SCRAM) mechanism, JWT 
token may be sent using one of the new mechanisms:
* OAUTHBEARER ([RFC 
7628|https://datatracker.ietf.org/doc/html/rfc7628#section-3])
* XOAUTH2 ([Google Gmail 
docs|https://developers.google.com/workspace/gmail/imap/xoauth2-protocol#the_sasl_xoauth2_mechanism])

(XOAUTH2 is marked as _OBSOLETE_ [at 
IANA|https://www.iana.org/assignments/sasl-mechanisms/sasl-mechanisms.xhtml]).

When implementing this JWT aware JAAS LoginModule, I've noticed that 
connections are associated with _credentials_ in quite static way. I.e., when 
connection attempt is authenticated, related objects are created and used for 
further communication.

However, with OAuth2 / OpenID Connection, the _credentials_ are more powerful 
and include expiration time.

It'd be great to have a mechanism, where the broker, at the time when 
connection is established and authenticated (whatever the messaging protocol 
is) should mark given connection as "valid till some specific time".

I'm not super-familiar with the mechanism used by browser for multi-protocol 
connection management, but I've created a crude change to 
{{org.apache.activemq.artemis.protocol.amqp.proton.AMQPConnectionContext#validateUser()}}
 method. This method has access to authenticated JAAS subject and 
OIDCLoginModule adds the entire token ({{com.nimbusds.jwt.JWT}} object) as one 
of the Subject's private credentials.

In this methods I've schedule a task to close the connection when the token 
validity time ends. Here's the far-from-perfect change (leaked task when the 
connection is closed earlier):
{code:java}
try {
org.apache.activemq.artemis.core.server.ActiveMQServer.validateUser()
   validatedUser = protocolManager.getServer().validateUser(user, password, 
connectionCallback.getProtonConnectionDelegate(), 
protocolManager.getSecurityDomain());
   Subject subject = 
connectionCallback.getProtonConnectionDelegate().getSubject();
   Set<JWT> jwts = subject.getPrivateCredentials(JWT.class);
   if (!jwts.isEmpty()) {
      JWT jwt = jwts.iterator().next();
      long exp = jwt.getJWTClaimsSet().getExpirationTime().getTime();
      long delay = exp - System.currentTimeMillis();
      if (delay > 0) {
         logger.debug("Scheduling connection close in {} seconds", delay/1000);
         this.scheduledPool.schedule(() -> {
            try {
               logger.debug("Closing the connection for token {}", 
jwt.getJWTClaimsSet().getJWTID());
            } catch (ParseException ignored) {
               // the token is already validated and parsed
            }
            connection.close();
         }, delay, TimeUnit.MILLISECONDS);
      } else {
         connection.close();
      }
   }
}
{code}

The login module from ARTEMIS-5200 is protocol agnostic.
However I checked the JWT authentication only over AMQP protocol.

I think Artemis could benefit from _enhanced credentials_ which turn:
bq. client connection + credentials
into
bq. client connection + credentials + expiration



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to