[ 
https://issues.apache.org/jira/browse/CASSANDRA-11471?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16008528#comment-16008528
 ] 

Ben Bromhead commented on CASSANDRA-11471:
------------------------------------------

bq. The original intent of this ticket was to enable multiple mechanisms to be 
supported simultaneously (e.g. use common name auth for encrypted connections 
if the certificates would allow it and fall back to password auth if not), but 
the patch as it is doesn't exactly do that. It seems to me that an admin could 
provide a custom IAuthenticator which had a list of mechanisms > 1 but it feels 
like that doesn't really improve on the status quo that much. Ideally, I think 
we need to be able to configure multiple IAuthenticators in yaml and have the 
client choose which of them to interact with. There are a few places which make 
an assumption that there is only a single IAuthenticator, so those would need 
to be addressed.

The idea behind this code (and admittedly it is somewhat shoehorned into this 
existing ticket), is to support negotiation for SASL mechanisms. While the SASL 
standard leaves the negotiation mechanism to the underlying protocol, the SASL 
authentication mechanisms are well defined (e.g. PLAIN, GSSAPI, etc) and 
controlled. One interpretation of the SASL standard, is the underlying protocol 
should define a negotiation mechanism and having a negotiation mechanism that 
changes based on the authentication implementation actually is not correct wrt 
to the SASL standard. 

Given this is a protocol level change (to cql), I think it makes sense for 
Cassandra to be opinionated about how the auth mechanism is negotiated rather 
than leaving it up to the individual IAuthenticator itself. 

This would also allow the driver to implement say SCRAM, or MD5 once and not 
actually care about the IAuthenticator mechanism. By introducing a defined 
negotiation mechanism into Cassandra, driver authors only need to implement a 
single authentication mechanism once and you won't have multiple GSSAPI 
implementations that target different IAuthenticator implementations. This 
change will also still let implementors of Authenticators do their own thing if 
they want to use a non-standard authentication mechanism. Supporting multiple 
auth mechanisms, while not the main intent of the ticket, was done mainly cause 
it was easy given we are already changing the CQL protocol to have a well 
defined authentication mechanism negotiation process.

bq. Following from that, I don't think that negotiation of the actual mechanism 
ought to be a function of the SASLNegotiator itself, at least not in it's 
current form (NegotiatingSaslNegotiator). Maybe we can compose the 
available/supported IAuthenticators into some class which aggregates them & 
have it perform the negotiation (i.e. selecting the instance based on the 
client's chosen mechanism). Or maybe this just happens in 
AuthResponse::execute. Basically, the actual IAuthenticator doesn't need to get 
involved until its mechanism has been selected.

This makes sense, but sticking with the above reasoning, I think Cassandra 
should still be responsible for negotiating what auth mechanism is used and 
then hand over to the implementation. It might make sense to pull this out, I 
left it in as part of IAuth mainly to reduce the amount of code changed and fit 
it in the existing implementation. However by my own logic, if C* is going to 
dictate negotiation, it should do this outside of the pluggable IAuth 
interface? I don't have any strong feelings either way tbh.

bq. Rather than adding a new factory method to IAuthenticator, wouldn't it be 
cleaner to add a withCertificates(Certificate[]) method with a default no-op 
implementation to SaslNegotiator? That way, the branching in ServerConnection 
is simplified, the need for the Optional is removed (because we just don't call 
it if the certs are null) and IAuthenticator impls which don't care about certs 
don't have to change at all.

That certainly seems cleaner to me! I'll give it a go.



> Add SASL mechanism negotiation to the native protocol
> -----------------------------------------------------
>
>                 Key: CASSANDRA-11471
>                 URL: https://issues.apache.org/jira/browse/CASSANDRA-11471
>             Project: Cassandra
>          Issue Type: Sub-task
>          Components: CQL
>            Reporter: Sam Tunnicliffe
>            Assignee: Ben Bromhead
>              Labels: client-impacting
>             Fix For: 4.x
>
>         Attachments: CASSANDRA-11471
>
>
> Introducing an additional message exchange into the authentication sequence 
> would allow us to support multiple authentication schemes and [negotiation of 
> SASL mechanisms|https://tools.ietf.org/html/rfc4422#section-3.2]. 
> The current {{AUTHENTICATE}} message sent from Client to Server includes the 
> java classname of the configured {{IAuthenticator}}. This could be superceded 
> by a new message which lists the SASL mechanisms supported by the server. The 
> client would then respond with a new message which indicates it's choice of 
> mechanism.  This would allow the server to support multiple mechanisms, for 
> example enabling both {{PLAIN}} for username/password authentication and 
> {{EXTERNAL}} for a mechanism for extracting credentials from SSL 
> certificates\* (see the example in 
> [RFC-4422|https://tools.ietf.org/html/rfc4422#appendix-A]). Furthermore, the 
> server could tailor the list of supported mechanisms on a per-connection 
> basis, e.g. only offering certificate based auth to encrypted clients. 
> The client's response should include the selected mechanism and any initial 
> response data. This is mechanism-specific; the {{PLAIN}} mechanism consists 
> of a single round in which the client sends encoded credentials as the 
> initial response data and the server response indicates either success or 
> failure with no futher challenges required.
> From a protocol perspective, after the mechanism negotiation the exchange 
> would continue as in protocol v4, with one or more rounds of 
> {{AUTH_CHALLENGE}} and {{AUTH_RESPONSE}} messages, terminated by an 
> {{AUTH_SUCCESS}} sent from Server to Client upon successful authentication or 
> an {{ERROR}} on auth failure. 
> XMPP performs mechanism negotiation in this way, 
> [RFC-3920|http://tools.ietf.org/html/rfc3920#section-6] includes a good 
> overview.
> \* Note: this would require some a priori agreement between client and server 
> over the implementation of the {{EXTERNAL}} mechanism.



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org
For additional commands, e-mail: commits-h...@cassandra.apache.org

Reply via email to