[
https://issues.apache.org/jira/browse/ARTEMIS-5983?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Grzegorz Grzybek updated ARTEMIS-5983:
--------------------------------------
Description:
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}
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
was:
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
> 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
> Priority: Major
> Labels: JAAS, oauth2, security
>
> 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}
> 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]