This work relates to
The Java Broker model has an authentication provider associated with each port. This means that a ssingle Broker may be configured to use more than one provider at once. For instance is is possible to use LDAP for messaging authentication and use OAUTH2 for management.
Currently the user's identity is represented by a simple string which contains the user's
comon name. This gives rise to the possibility that a user with common name fred from one authentication provider is indistinguishable for a fred from another authentication provider.
This problem manifests currently:
- Groups are produced by mapping a common name to a group name. Currently we have no way of preventing all fred (a messaging user) from being put in the admins group because there is also fred who is an admin.
- The audit trail produced in the log contains only the common name. An action by one fred is indistinguishable from actions of another fred.
- The audit attributes of the configured object capture the common. An queue created by fred carries a createdBy value 'fred'.
- An application producing a message captures the authenticated identity and records this in the
JMSXUserId
property of each message. If two applications, using separate AMQP ports using separate authentication provides both have a user called fred, the consuming application has no way to distinguish which fred produced the message. - For messages produced by client authenticating with
X-OAuth2
currently have noJMSXUserId
. This is because the messaging client is not aware of the authenticated common name - Sometimes common names aren't easily interpretted by a human user. For instance, in the case of Google's OAuth the common name is a 14 digit number. A operator examining using Qpid has no way to discover the human name of the user who performed an action.
The problem has a bearing on the High Availability (HA) use case too. There is already an implict restriction when using HA that all Brokers have authentication providers configured in the same way. If this were not the case, applications could not fail over between nodes in the cluster. It could also mean that the identities associated with configured objects (for instance a queue's createdBy attribute) or a message's JMSXUser becomes 'unresolvable' after the group has changed mastership.
The problem will also have a bearing on the federation case too.
Constraints
- User identities need to be representable as a string (so that they an be serialised as JSON)
- The user identity belongs to source identification system. Qpid should be capable of using these identifiers as they stand. It should not invent its own unique user id.
- The identification system may or may not permit an artbitarry user identity to resolved into the corresponding human name. For instance, some (LDAP) Directories require that that user authenticates (binds) before that information is returned.
- The messaging client must contain to authenticate using a common name
Ideas
We discussed the idea of adopting RFC-4120 naming conventions where each common name would be qualified by a realm name:
<encoded common name>@<realm>
where realm name would be as per Section 6 of RFC-4120.
domain: ATHENA.MIT.EDU X500: C=US/O=OSF other: NAMETYPE:rest/of.name=without-restrictions
e.g.
The AuthenticationProvider would change so that they contribute identities from one or more realms. Some AuthenticationProviders (e.g. Kerberos) would do this 'natively'. For other authentication providers that don't share the same notion, the the user would assign a synthetic realm. This would mean that all identities within Qpid followed the same realm qualified user identity scheme.
Perhaps an identity from a config backed SHA256 might look like:
keith@qpid:SCRAM-SHA256/myscramprovider
A business rule would ensure that no two providers yield identities from the same realm.
The AuthenticationProvider would acquire a responsibility to resolve an arbitrary realm qualified user identity into its human readable name. For some authentication providers, they may be able to perform a live lookup against the identity backend. For others this may be disallowed. To accomodate this case the authentication provider may cache certain details about users as they login, so later, those details can be returned. This information will allow the operator to know it was Joe Bloggs who created a queue or sent a message. This part of the system needs to be aware that some identities may not have human readable names (common in ids used for system to system communication).
Messaging
The messaging client currently knows only the common name which it used to identify itself to Qpid. It also uses this common name when populating the JMSXUser property in the message header of produced messages. We will want the JMSXUser to be populated with the realm qualified identity.
The Broker would need to be aware that older clients may in use and this would still send the
common name. The Broker should tolerate such messages (perhaps configurable).
Upgrade
The configuration upgrader should upgrade the authentication providers to have realm (how would we manufacture the realm names). The lastUpdatedBy and createdBy attributes of existing objects could be upgraded too in the common case where only one provider is in use.
The store upgrader could apply the same rules and upgrade message headers (it is worth it?)