Hi Ron/Stansilav,

OK, let's just go with 2. I think it would be better to add a
OAuth-specific extensions handler OAuthBearerExtensionsValidatorCallback that
provides OAuthBearerToken.

To summarise, we chose option 2 out of these four options:

   1. {OAuthBearerValidatorCallback, SaslExtensionsValidatorCallback} : We
   don't want to use multiple ordered callbacks since we don't want the
   context of one callback to come from another.callback,
   2. OAuthBearerExtensionsValidatorCallback(OAuthBearerToken token,
   SaslExtensions ext): This allows extensions to be validated using
   context from the token, we are ok with this.
   3. SaslExtensionsValidatorCallback(Map<String, Object> context,
   SaslExtensions ext): This doesn't really offer any real advantage over 2.
   4. OAuthBearerValidatorCallback(String token, SaslExtensions ext): We
   don't want token validator to see extensions since these are insecure but
   token validation needs to be secure. So we prefer to use a second callback
   handler to validate extensions after securely validating token.



On Wed, Aug 8, 2018 at 8:52 PM, Ron Dagostino <rndg...@gmail.com> wrote:

> Hi Rajini.  I think we are considering the following two options.  Let me
> try to describe them along with their relative advantages/disadvantages.
>
> Option #1: Send two callbacks in a single array to the callback handler:
>     ch.handle(new Callback[] {tokenCallback, extensionsCallback});
>
> Option #2: Send two callbacks separately, in two separate arrays, to the
> callback handler:
>     ch.handle(new Callback[] {tokenCallback});
>     ch.handle(new Callback[] {extensionsCallback});
>
> I actually don't see any objective disadvantage with #1.  If we don't get
> an exception then we know we have the information we need; if we do get an
> exception then we can tell if the first callback was handled because either
> its token() method or its errorStatus() method will return non-null; if
> both return null then we just send the token callback by itself and we
> don't publish any extension as negotiated properties.  There is no
> possibility of partial results, and I don't think there is a performance
> penalty due to potential re-validation here, either.
>
> I  see a subjective disadvantage with #1.  It feels awkward to me to
> provide the token as context for extension validation via the first
> callback.
>
> Actually, it just occurred to me why it feels awkward, and I think this is
> an objective disadvantage of this approach.  It would be impossible to do
> extension validation in such a scenario without also doing token validation
> first.  We are using the first callback as a way to provide context, but we
> are also using that first callback to request token validation.  We are
> complecting two separate things -- context and a request for validation --
> into one thing, so this approach has an element of complexity to it.
>
> The second option has no such complexity.  If we want to provide context to
> the extension validation then we do that by adding a token to the
> extensionsCallback instance before we provide it to the callback handler.
> How we do that -- whether by Map<String, Object> or via a typed getter --
> feels like a subjective decision, and assuming you agree with the
> complexity argument and choose option #2, I would defer to your preference
> as to how to implement it.
>
> Ron
>
>
>
>
>
>
>
>
>
>
>
>
> On Wed, Aug 8, 2018 at 3:10 PM Rajini Sivaram <rajinisiva...@gmail.com>
> wrote:
>
> > Hi Ron,
> >
> > Yes, I was thinking of a SaslExtensionsValidatorCallback with additional
> > context as well initially, but I didn't like the idea of name-value pairs
> > and I didn't want generic  objects passed around through the callback  So
> > providing context through other callbacks felt like a neater fit. There
> > are pros and cons for both approaches, so we could go with either.
> >
> > Callbacks are provided to callback handlers in an array and there is
> > implicit ordering in the callbacks provided to the callback handler.
> > In the typical example of {NameCallback, PasswordCallback}, we expect
> that
> > ordering so that password callback knows what the user name is. Kafka
> > guarantees ordering of server callbacks in each of its SASL mechanisms
> and
> > this is explicitly stated in
> >
> > https://cwiki.apache.org/confluence/display/KAFKA/KIP-
> 86%3A+Configurable+SASL+callback+handlers
> > .
> > Until now, we didn't need to worry about ordering for OAuth.
> >
> > We currently do not have any optional callbacks - configured callback
> > handlers have to process all the callbacks for the mechanism or else we
> > fail authentication. We have to make SaslExtensionValidationCallback an
> > exception, at least for backward compatibility. We will only include this
> > callback if the client provided some extensions. I think it is reasonable
> > to expect that in general, custom callback handlers will handle this
> > callback if clients are likely to set extensions.  In case it doesn't, we
> > don't want to make any assumptions about which callbacks may have been
> > handled. Instead, it would be better to invoke the callback handler again
> > without the extensions callback and not expose any extensions as
> negotiated
> > properties. Since we are doing this only for backward compatibility, the
> > small performance hit would be reasonable, avoiding any assumptions about
> > the callback handler implementation and partial results on hitting an
> > exception.
> >
> > Back to the other approach of providing a Map. For OAuth, we would like
> > extension validation to see the actual OAuthBearerToken object, for
> > instance to validate extensions based on scope. Having
> > these mechanism-specific objects in a Map doesn't feel ideal. It will
> > probably be better to define OAuthBearerExtensionsValidatorCallback
> with a
> > token getter that returns OAuthBearerToken in that case.
> >
> > Thoughts?
> >
> >
> > On Wed, Aug 8, 2018 at 6:09 PM, Ron Dagostino <rndg...@gmail.com> wrote:
> >
> > > Hi Rajini.  I also like that idea, but I think it might rely on one or
> > > possibly two implicit assumptions that I'm not sure are guaranteed to
> be
> > > true.  First, I'm not sure if the CallbackHandler interface guarantees
> > that
> > > implementations must process callbacks in order.  Second (and more
> > > plausibly than the first), I'm not sure CallbackHandler guarantees that
> > > callbacks are to be processed in order until either there are no more
> > left
> > > in the array or one of the elements is an unsupported callback.  The
> > > Javadoc simply says it throws UnsupportedCallbackException "if the
> > > implementation of this method does not support one or more of the
> > Callbacks
> > > specified in the callbacks parameter." This statement does not preclude
> > the
> > > case that implementations might first check to make sure all of the
> > > provided callbacks are supported before processing any of them.
> > >
> > > We could update the Javadoc for AuthenticateCallbackHandler to make it
> > > clear how implementations must work -- i.e. they must process the
> > callbacks
> > > in order, and they must process all recognized callbacks before
> throwing
> > > UnsupportedCallbackException due to an unrecognized one.
> > >
> > > Note that the above issue does not arise if we simply want the ability
> to
> > > validate SASL extensions in isolation -- we could just give the
> callback
> > > handler an array containing a single instance of the proposed
> > > SaslExtensionsValidatorCallback.The issue only arises if we want to
> > > provide
> > > additional context (e.g. the token in the case of SASL/OATHBEARER) to
> the
> > > validation mechanism.
> > >
> > > If it is not just SASL Extension validation that we are interested in
> > > adding but in fact we want to be able to provide additional context to
> > > SaslExtensionsValidatorCallback, then adding the ordering constraint
> > above
> > > is one way, but we could avoid the constraint by allowing
> > > SaslExtensionsValidatorCallback to accept not only the extensions to
> > > validate but also an arbitrary map of name/value pairs.  Each SASL
> > > mechanism implementation could declare what additional context it
> > provides
> > > (if any) and at what key(s) the information is available.  This second
> > > approach feels more direct than the first one and would be my
> preference
> > > (assuming I',m not missing anything, which is certainly possible).
> > > Thoughts?
> > >
> > > Ron
> > >
> > >
> > > On Wed, Aug 8, 2018 at 12:39 PM Stanislav Kozlovski <
> > > stanis...@confluent.io>
> > > wrote:
> > >
> > > > Hi Rajini,
> > > >
> > > > That approach makes more sense to me. I like it
> > > >
> > > > On Wed, Aug 8, 2018 at 5:35 PM Rajini Sivaram <
> rajinisiva...@gmail.com
> > >
> > > > wrote:
> > > >
> > > > > Hi Ron/Stanislav,
> > > > >
> > > > > Do you think it makes sense to separate out
> > > OAuthBearerValidatorCallback
> > > > > and SaslExtensionsValidatorCallback so that it is clearer that
> these
> > > are
> > > > > two separate entities that need validation? When we add support
> > > > > for customisable extensions in other mechanisms, we could reuse
> > > > > SaslExtensionsValidatorCallback. We will invoke CallbackHandler
> with
> > {
> > > > > OAuthBearerValidatorCallback, SaslExtensionsValidatorCallback } in
> > > that
> > > > > order like we do { NameCallback, PasswordCallback }. So typically
> we
> > > > expect
> > > > > to validate tokens with no reference to extensions, but we may
> refer
> > to
> > > > > token to validate extensions. Only validated extensions will be
> > > available
> > > > > as the server's negotiated properties. We will need to handle
> > > > > UnsupportedCallbackException for SaslExtensionsValidatorCallback
> for
> > > > > backwards compatibility, but that should be ok.
> > > > >
> > > > > What do you think?
> > > > >
> > > > >
> > > > > On Wed, Aug 8, 2018 at 5:06 PM, Stanislav Kozlovski <
> > > > > stanis...@confluent.io>
> > > > > wrote:
> > > > >
> > > > > > Hi Ron,
> > > > > >
> > > > > > Yes, I agree we should document it thoroughly
> > > > > >
> > > > > > On Wed, Aug 8, 2018 at 5:02 PM Ron Dagostino <rndg...@gmail.com>
> > > > wrote:
> > > > > >
> > > > > > > Hi Stanislav.  If the community agrees we should add it then we
> > > > should
> > > > > > at a
> > > > > > > minimum add explicit warnings in the Javadoc making it very
> clear
> > > how
> > > > > > this
> > > > > > > should not be used.
> > > > > > >
> > > > > > > Ron
> > > > > > >
> > > > > > > On Wed, Aug 8, 2018 at 11:54 AM Stanislav Kozlovski <
> > > > > > > stanis...@confluent.io>
> > > > > > > wrote:
> > > > > > >
> > > > > > > > Hey Ron,
> > > > > > > >
> > > > > > > > I fully agree that token validation is a serious security
> > > > operation.
> > > > > > > > Although, I believe allowing the user to do more validation
> > with
> > > > the
> > > > > > > > extensions does not hurt - the user is fully responsible for
> > his
> > > > > > security
> > > > > > > > once he starts implementing custom code for token validation.
> > You
> > > > > would
> > > > > > > > expect people to take the appropriate considerations when
> > > > validating
> > > > > > > > unsecured extensions against the token.
> > > > > > > > I also think that using the extensions as a secondary
> > validation
> > > > > method
> > > > > > > > might be useful. You could do your normal validation using
> the
> > > > token
> > > > > > and
> > > > > > > > then have a second sanity-check validation on top (e.g
> validate
> > > > > > > > hostname/port is what client expected). Keep in mind that the
> > > > server
> > > > > > > > exposes the properties via `getNegotiatedProperty` so it
> makes
> > > > sense
> > > > > to
> > > > > > > > allow the server to have custom validation on the extensions.
> > > > > > > >
> > > > > > > > Best,
> > > > > > > > Stanislav
> > > > > > > >
> > > > > > > > On Wed, Aug 8, 2018 at 3:29 PM Ron Dagostino <
> > rndg...@gmail.com>
> > > > > > wrote:
> > > > > > > >
> > > > > > > > > Hi Stanislav.  If you wanted to do this a good way might be
> > to
> > > > add
> > > > > a
> > > > > > > > > constructor to the org.apache.kafka.common.
> > > security.oauthbearer.
> > > > > > > > > OAuthBearerValidatorCallback class that accepts a
> > > SaslExtensions
> > > > > > > instance
> > > > > > > > > in addition to a token value.  Then it would give the
> > callback
> > > > > > handler
> > > > > > > > the
> > > > > > > > > option to introspect the callback to see what extensions
> were
> > > > > > provided
> > > > > > > > with
> > > > > > > > > the
> > > > > > > > > token.
> > > > > > > > >
> > > > > > > > > That being said, token validation is a very
> > security-sensitive
> > > > > > > operation,
> > > > > > > > > and it would be a serious security issue if the result of
> > > > applying
> > > > > > the
> > > > > > > > > validation algorithm (which yields a valid vs. not valid
> > > > > > determination)
> > > > > > > > > depended on anything provided by the client other than the
> > > actual
> > > > > > token
> > > > > > > > > value.  Nobody should ever allow the client to specify a
> JWK
> > > Set
> > > > > URL,
> > > > > > > for
> > > > > > > > > example, or a whitelist of acceptable domains for
> retrieving
> > > JWK
> > > > > > Sets.
> > > > > > > > It
> > > > > > > > > feels to me that while a use case might exist (some kind of
> > > trace
> > > > > ID,
> > > > > > > for
> > > > > > > > > example, to aid in debugging), someone might inadvertently
> > hang
> > > > > > > > themselves
> > > > > > > > > if we give them the rope.  The risk vs. reward value
> > > proposition
> > > > > here
> > > > > > > > > doesn't feel like a good one at first glance.  Thoughts?
> > > > > > > > >
> > > > > > > > > Ron
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > On Wed, Aug 8, 2018 at 10:04 AM Stanislav Kozlovski <
> > > > > > > > > stanis...@confluent.io>
> > > > > > > > > wrote:
> > > > > > > > >
> > > > > > > > > > Hey everybody,
> > > > > > > > > >
> > > > > > > > > > Sorry for reviving this, but I neglected something the
> > first
> > > > time
> > > > > > > > around.
> > > > > > > > > > I believe it would be useful to provide the
> > > > > > > > > > `OAuthBearerUnsecuredValidatorCallbackHandler` with the
> > > OAuth
> > > > > > > > extensions
> > > > > > > > > > too. This would enable use cases where validators want to
> > > > > reconcile
> > > > > > > > > > information from the extensions with the token (e.g if
> > users
> > > > have
> > > > > > > > > > implemented secured OAuth tokens).
> > > > > > > > > > The implementation would be to instantiate
> > > > > > > > > > `OAuthBearerUnsecuredValidatorCallback` with the
> extensions
> > > > (also
> > > > > > > leave
> > > > > > > > > the
> > > > > > > > > > current constructor, as its a public class).
> > > > > > > > > >
> > > > > > > > > > What are everybody's thoughts on this? If there are no
> > > > > objections,
> > > > > > > I'll
> > > > > > > > > > update the KIP in due time
> > > > > > > > > >
> > > > > > > > > > On Thu, Jul 26, 2018 at 11:14 AM Rajini Sivaram <
> > > > > > > > rajinisiva...@gmail.com
> > > > > > > > > >
> > > > > > > > > > wrote:
> > > > > > > > > >
> > > > > > > > > > > Looks good. Thanks, Stanislav.
> > > > > > > > > > >
> > > > > > > > > > > On Wed, Jul 25, 2018 at 7:46 PM, Stanislav Kozlovski <
> > > > > > > > > > > stanis...@confluent.io
> > > > > > > > > > > > wrote:
> > > > > > > > > > >
> > > > > > > > > > > > Hi Rajini,
> > > > > > > > > > > >
> > > > > > > > > > > > I updated the KIP. Please check if the clarification
> is
> > > > okay
> > > > > > > > > > > >
> > > > > > > > > > > > On Wed, Jul 25, 2018 at 10:49 AM Rajini Sivaram <
> > > > > > > > > > rajinisiva...@gmail.com
> > > > > > > > > > > >
> > > > > > > > > > > > wrote:
> > > > > > > > > > > >
> > > > > > > > > > > > > Hi Stanislav,
> > > > > > > > > > > > >
> > > > > > > > > > > > > 1. Can you clarify the following line in the KIP in
> > the
> > > > > > 'Public
> > > > > > > > > > > > Interfaces'
> > > > > > > > > > > > > section? When you are reading the KIP for the first
> > > time,
> > > > > it
> > > > > > > > sounds
> > > > > > > > > > > like
> > > > > > > > > > > > we
> > > > > > > > > > > > > adding a new Kafka config. But we are adding JAAS
> > > config
> > > > > > > options
> > > > > > > > > > with a
> > > > > > > > > > > > > prefix that can be used with the default unsecured
> > > bearer
> > > > > > > tokens.
> > > > > > > > > We
> > > > > > > > > > > > could
> > > > > > > > > > > > > include the example in this section or at least
> link
> > to
> > > > the
> > > > > > > > > example.
> > > > > > > > > > > > >
> > > > > > > > > > > > >    - New config option for default, unsecured
> bearer
> > > > > tokens -
> > > > > > > > > > > > >    `unsecuredLoginExtension_<extensionname>`.
> > > > > > > > > > > > >
> > > > > > > > > > > > >
> > > > > > > > > > > > > 2. Can you add the package for
> SaslExtensionsCallback
> > > > > class?
> > > > > > > > > > > > >
> > > > > > > > > > > > >
> > > > > > > > > > > > > On Tue, Jul 24, 2018 at 10:03 PM, Stanislav
> > Kozlovski <
> > > > > > > > > > > > > stanis...@confluent.io> wrote:
> > > > > > > > > > > > >
> > > > > > > > > > > > > > Hi Ron,
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > Thanks for the suggestions. I have applied them
> to
> > > the
> > > > > KIP.
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > On Tue, Jul 24, 2018 at 1:39 PM Ron Dagostino <
> > > > > > > > rndg...@gmail.com
> > > > > > > > > >
> > > > > > > > > > > > wrote:
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > > Hi Stanislav.  The statement "New config option
> > for
> > > > > > > > > > > > > > OAuthBearerLoginModule"
> > > > > > > > > > > > > > > is technically incorrect; it should be "New
> > config
> > > > > option
> > > > > > > for
> > > > > > > > > > > > default,
> > > > > > > > > > > > > > > unsecured bearer tokens" since that is what
> > > provides
> > > > > the
> > > > > > > > > > > > functionality
> > > > > > > > > > > > > > (as
> > > > > > > > > > > > > > > opposed to the login module, which does not).
> > > Also,
> > > > > > please
> > > > > > > > > state
> > > > > > > > > > > > that
> > > > > > > > > > > > > > > "auth" is not supported as a custom extension
> > name
> > > > with
> > > > > > any
> > > > > > > > > > > > > > > SASL/OAUTHBEARER mechanism, including the
> > unsecured
> > > > > one,
> > > > > > > > since
> > > > > > > > > it
> > > > > > > > > > > is
> > > > > > > > > > > > > > > reserved by the spec for what is normally sent
> in
> > > the
> > > > > > HTTP
> > > > > > > > > > > > > Authorization
> > > > > > > > > > > > > > > header an attempt to use it will result in a
> > > > > > configuration
> > > > > > > > > > > exception.
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > Finally, please also state that while the
> > > > > > > > > OAuthBearerLoginModule
> > > > > > > > > > > and
> > > > > > > > > > > > > the
> > > > > > > > > > > > > > > OAuthBearerSaslClient will be changed to
> request
> > > the
> > > > > > > > extensions
> > > > > > > > > > > from
> > > > > > > > > > > > > its
> > > > > > > > > > > > > > > callback handler, for backwards compatibility
> it
> > is
> > > > not
> > > > > > > > > necessary
> > > > > > > > > > > for
> > > > > > > > > > > > > the
> > > > > > > > > > > > > > > callback handler to support
> > SaslExtensionsCallback
> > > --
> > > > > any
> > > > > > > > > > > > > > > UnsupportedCallbackException that is thrown
> will
> > be
> > > > > > ignored
> > > > > > > > and
> > > > > > > > > > no
> > > > > > > > > > > > > > > extensions will be added.
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > Ron
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > On Tue, Jul 24, 2018 at 11:20 AM Stanislav
> > > Kozlovski
> > > > <
> > > > > > > > > > > > > > > stanis...@confluent.io>
> > > > > > > > > > > > > > > wrote:
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > Hey everybody,
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > I have updated the KIP to reflect the latest
> > > > changes
> > > > > as
> > > > > > > > best
> > > > > > > > > > as I
> > > > > > > > > > > > > > could.
> > > > > > > > > > > > > > > If
> > > > > > > > > > > > > > > > there aren't more suggestions, I intent to
> > start
> > > > the
> > > > > > > [VOTE]
> > > > > > > > > > > thread
> > > > > > > > > > > > > > > > tomorrow.
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > Best,
> > > > > > > > > > > > > > > > Stanislav
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > On Tue, Jul 24, 2018 at 6:34 AM Ron
> Dagostino <
> > > > > > > > > > rndg...@gmail.com
> > > > > > > > > > > >
> > > > > > > > > > > > > > wrote:
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > Hi Stanislav.  Could you update the KIP to
> > > > reflect
> > > > > > the
> > > > > > > > > latest
> > > > > > > > > > > > > > > definition
> > > > > > > > > > > > > > > > of
> > > > > > > > > > > > > > > > > SaslExtensions and confirm or correct the
> > > impact
> > > > it
> > > > > > has
> > > > > > > > to
> > > > > > > > > > the
> > > > > > > > > > > > > > > > > SCRAM-related classes?  I'm not sure if the
> > > > > > > > > > currently-described
> > > > > > > > > > > > > > impact
> > > > > > > > > > > > > > > is
> > > > > > > > > > > > > > > > > still accurate.  Also, could you mention
> the
> > > > > changes
> > > > > > to
> > > > > > > > > > > > > > > > > OAuthBearerUnsecuredLoginCallbackHandler
> in
> > > the
> > > > > > text in
> > > > > > > > > > > > addition to
> > > > > > > > > > > > > > > > giving
> > > > > > > > > > > > > > > > > the examples?  The examples show the new
> > > > > > > > > > > > > > > > > unsecuredLoginExtension_<extensionName>
> > > feature,
> > > > > but
> > > > > > > that
> > > > > > > > > > > > feature
> > > > > > > > > > > > > is
> > > > > > > > > > > > > > > not
> > > > > > > > > > > > > > > > > described anywhere prior to it appearing
> > there.
> > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > Ron
> > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > On Mon, Jul 23, 2018 at 1:42 PM Ron
> > Dagostino <
> > > > > > > > > > > rndg...@gmail.com
> > > > > > > > > > > > >
> > > > > > > > > > > > > > > wrote:
> > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > Hi Rajini.  I think a class is fine as
> long
> > > as
> > > > we
> > > > > > > make
> > > > > > > > > sure
> > > > > > > > > > > the
> > > > > > > > > > > > > > > > semantics
> > > > > > > > > > > > > > > > > > of immutability are clear -- it would
> have
> > to
> > > > be
> > > > > a
> > > > > > > > value
> > > > > > > > > > > class,
> > > > > > > > > > > > > and
> > > > > > > > > > > > > > > any
> > > > > > > > > > > > > > > > > > constructor that accepts a Map as input
> > would
> > > > > have
> > > > > > to
> > > > > > > > > copy
> > > > > > > > > > > that
> > > > > > > > > > > > > Map
> > > > > > > > > > > > > > > > > rather
> > > > > > > > > > > > > > > > > > than store it in a member variable.
> > > Similarly,
> > > > > any
> > > > > > > Map
> > > > > > > > > > that
> > > > > > > > > > > it
> > > > > > > > > > > > > > might
> > > > > > > > > > > > > > > > > > return would have to be unmodifiable.
> > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > Ron
> > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > On Mon, Jul 23, 2018 at 12:24 PM Rajini
> > > > Sivaram <
> > > > > > > > > > > > > > > > rajinisiva...@gmail.com
> > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > wrote:
> > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > >> Hi Ron, Stanislav,
> > > > > > > > > > > > > > > > > >>
> > > > > > > > > > > > > > > > > >> I agree with Stanislav that it would be
> > > better
> > > > > to
> > > > > > > > leave
> > > > > > > > > > > > > > > > `SaslExtensions`
> > > > > > > > > > > > > > > > > >> as
> > > > > > > > > > > > > > > > > >> a class rather than make it an
> interface.
> > We
> > > > > > don''t
> > > > > > > > > really
> > > > > > > > > > > > > expect
> > > > > > > > > > > > > > > > users
> > > > > > > > > > > > > > > > > to
> > > > > > > > > > > > > > > > > >> extends this class, so it is convenient
> to
> > > > have
> > > > > an
> > > > > > > > > > > > > implementation
> > > > > > > > > > > > > > > > since
> > > > > > > > > > > > > > > > > >> users need to create an instance. The
> > class
> > > > > > provided
> > > > > > > > by
> > > > > > > > > > the
> > > > > > > > > > > > > public
> > > > > > > > > > > > > > > API
> > > > > > > > > > > > > > > > > >> should be sufficient in the vast
> majority
> > of
> > > > the
> > > > > > > > cases.
> > > > > > > > > > Ron,
> > > > > > > > > > > > do
> > > > > > > > > > > > > > you
> > > > > > > > > > > > > > > > > agree?
> > > > > > > > > > > > > > > > > >>
> > > > > > > > > > > > > > > > > >> On Mon, Jul 23, 2018 at 11:35 AM, Ron
> > > > Dagostino
> > > > > <
> > > > > > > > > > > > > > rndg...@gmail.com>
> > > > > > > > > > > > > > > > > >> wrote:
> > > > > > > > > > > > > > > > > >>
> > > > > > > > > > > > > > > > > >> > Hi Stanislav.  See
> > > > > > > > > > > > > > > https://tools.ietf.org/html/
> rfc7628#section-3.1,
> > > > > > > > > > > > > > > > > and
> > > > > > > > > > > > > > > > > >> > that section refers to the core ABNF
> > > > > productions
> > > > > > > > > defined
> > > > > > > > > > > in
> > > > > > > > > > > > > > > > > >> >
> > > > > https://tools.ietf.org/html/rfc5234#appendix-B.
> > > > > > > > > > > > > > > > > >> >
> > > > > > > > > > > > > > > > > >> > Ron
> > > > > > > > > > > > > > > > > >> >
> > > > > > > > > > > > > > > > > >> > > On Jul 23, 2018, at 1:30 AM,
> Stanislav
> > > > > > > Kozlovski <
> > > > > > > > > > > > > > > > > >> stanis...@confluent.io>
> > > > > > > > > > > > > > > > > >> > wrote:
> > > > > > > > > > > > > > > > > >> > >
> > > > > > > > > > > > > > > > > >> > > Hey Ron and Rajini,
> > > > > > > > > > > > > > > > > >> > >
> > > > > > > > > > > > > > > > > >> > > Here are my thoughts:
> > > > > > > > > > > > > > > > > >> > > Regarding separators in
> > SaslExtensions -
> > > > > > Agreed,
> > > > > > > > > that
> > > > > > > > > > > was
> > > > > > > > > > > > a
> > > > > > > > > > > > > > bad
> > > > > > > > > > > > > > > > > move.
> > > > > > > > > > > > > > > > > >> > > Should definitely not be a concern
> of
> > > > > > > > > CallbackHandler
> > > > > > > > > > > and
> > > > > > > > > > > > > > > > > LoginModule
> > > > > > > > > > > > > > > > > >> > > implementors.
> > > > > > > > > > > > > > > > > >> > > SaslExtensions interface - Wouldn't
> > > > > > implementing
> > > > > > > > it
> > > > > > > > > as
> > > > > > > > > > > an
> > > > > > > > > > > > > > > > interface
> > > > > > > > > > > > > > > > > >> mean
> > > > > > > > > > > > > > > > > >> > > that users will have to make sure
> > > they're
> > > > > > > passing
> > > > > > > > in
> > > > > > > > > > an
> > > > > > > > > > > > > > > > unmodifiable
> > > > > > > > > > > > > > > > > >> map
> > > > > > > > > > > > > > > > > >> > > themselves. I believe it would be
> > better
> > > > if
> > > > > we
> > > > > > > > > > enforced
> > > > > > > > > > > > that
> > > > > > > > > > > > > > > > through
> > > > > > > > > > > > > > > > > >> > class
> > > > > > > > > > > > > > > > > >> > > constructors instead.
> > > > > > > > > > > > > > > > > >> > > SaslExtensions#map() - I'd also
> prefer
> > > > this.
> > > > > > The
> > > > > > > > > > reason
> > > > > > > > > > > I
> > > > > > > > > > > > > went
> > > > > > > > > > > > > > > > with
> > > > > > > > > > > > > > > > > >> > > `extensionValue` and
> `extensionNames`
> > > was
> > > > > > > because
> > > > > > > > I
> > > > > > > > > > > > figured
> > > > > > > > > > > > > it
> > > > > > > > > > > > > > > > made
> > > > > > > > > > > > > > > > > >> sense
> > > > > > > > > > > > > > > > > >> > > to have `ScramExtensions` extend
> > > > > > > `SaslExtensions`
> > > > > > > > > and
> > > > > > > > > > > > > > therefore
> > > > > > > > > > > > > > > > have
> > > > > > > > > > > > > > > > > >> > their
> > > > > > > > > > > > > > > > > >> > > API be similar. In the end, do you
> > think
> > > > > that
> > > > > > it
> > > > > > > > is
> > > > > > > > > > > worth
> > > > > > > > > > > > it
> > > > > > > > > > > > > > to
> > > > > > > > > > > > > > > > have
> > > > > > > > > > > > > > > > > >> > > `ScramExtensions` extend
> > > `SaslExtensions`?
> > > > > > > > > > > > > > > > > >> > > @Ron, could you point me to the SASL
> > > OAuth
> > > > > > > > mechanism
> > > > > > > > > > > > > specific
> > > > > > > > > > > > > > > > > regular
> > > > > > > > > > > > > > > > > >> > > expressions for keys/values you
> > > mentioned
> > > > > are
> > > > > > in
> > > > > > > > RFC
> > > > > > > > > > > 7628
> > > > > > > > > > > > (
> > > > > > > > > > > > > > > > > >> > > https://tools.ietf.org/html/rfc7628
> )
> > ?
> > > I
> > > > > > could
> > > > > > > > not
> > > > > > > > > > find
> > > > > > > > > > > > any
> > > > > > > > > > > > > > > while
> > > > > > > > > > > > > > > > > >> > > originally implementing this.
> > > > > > > > > > > > > > > > > >> > >
> > > > > > > > > > > > > > > > > >> > > Best,
> > > > > > > > > > > > > > > > > >> > > Stanislav
> > > > > > > > > > > > > > > > > >> > >
> > > > > > > > > > > > > > > > > >> > >> On Sun, Jul 22, 2018 at 6:46 PM Ron
> > > > > > Dagostino <
> > > > > > > > > > > > > > > rndg...@gmail.com
> > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > >> > wrote:
> > > > > > > > > > > > > > > > > >> > >>
> > > > > > > > > > > > > > > > > >> > >> Hi again, Rajini and Stanislav.  I
> > > wonder
> > > > > if
> > > > > > > > making
> > > > > > > > > > > > > > > > SaslExtensions
> > > > > > > > > > > > > > > > > an
> > > > > > > > > > > > > > > > > >> > >> interface rather than a class might
> > be
> > > a
> > > > > good
> > > > > > > > > > solution.
> > > > > > > > > > > > > For
> > > > > > > > > > > > > > > > > example:
> > > > > > > > > > > > > > > > > >> > >>
> > > > > > > > > > > > > > > > > >> > >> public interface SaslExtensions {
> > > > > > > > > > > > > > > > > >> > >>   /**
> > > > > > > > > > > > > > > > > >> > >>    * @return an immutable map view
> of
> > > the
> > > > > > SASL
> > > > > > > > > > > extensions
> > > > > > > > > > > > > > > > > >> > >>    */
> > > > > > > > > > > > > > > > > >> > >>    Map<String, String> map();
> > > > > > > > > > > > > > > > > >> > >> }
> > > > > > > > > > > > > > > > > >> > >>
> > > > > > > > > > > > > > > > > >> > >> This solves the issue of lack of
> > > clarity
> > > > on
> > > > > > > > > > > immutability,
> > > > > > > > > > > > > and
> > > > > > > > > > > > > > > it
> > > > > > > > > > > > > > > > > also
> > > > > > > > > > > > > > > > > >> > >> eliminates copying, like this:
> > > > > > > > > > > > > > > > > >> > >>
> > > > > > > > > > > > > > > > > >> > >> SaslExtensions myMethod() {
> > > > > > > > > > > > > > > > > >> > >>    Map<String, String> myRetval =
> > > > > > > > > > > > > > > > > getUnmodifiableSaslExtensionsMap();
> > > > > > > > > > > > > > > > > >> > >>    return new SaslExtensions() {
> > > > > > > > > > > > > > > > > >> > >>        public Map<String, String>
> > > map() {
> > > > > > > > > > > > > > > > > >> > >>            return myRetval;
> > > > > > > > > > > > > > > > > >> > >>        }
> > > > > > > > > > > > > > > > > >> > >>    }
> > > > > > > > > > > > > > > > > >> > >> }
> > > > > > > > > > > > > > > > > >> > >>
> > > > > > > > > > > > > > > > > >> > >> Alternatively, we could do it like
> > > this:
> > > > > > > > > > > > > > > > > >> > >>
> > > > > > > > > > > > > > > > > >> > >> /**
> > > > > > > > > > > > > > > > > >> > >> * Supplier that returns immutable
> map
> > > > view
> > > > > of
> > > > > > > > SASL
> > > > > > > > > > > > > Extensions
> > > > > > > > > > > > > > > > > >> > >> */
> > > > > > > > > > > > > > > > > >> > >> public interface SaslExtensions
> > extends
> > > > > > > > > > > > > Supplier<Map<String,
> > > > > > > > > > > > > > > > > >> String>> {
> > > > > > > > > > > > > > > > > >> > >>    // empty
> > > > > > > > > > > > > > > > > >> > >> }
> > > > > > > > > > > > > > > > > >> > >>
> > > > > > > > > > > > > > > > > >> > >> The we could simply return the
> > instance
> > > > > like
> > > > > > > > this,
> > > > > > > > > > > again
> > > > > > > > > > > > > > > without
> > > > > > > > > > > > > > > > > >> > copying:
> > > > > > > > > > > > > > > > > >> > >>
> > > > > > > > > > > > > > > > > >> > >> SaslExtensions myMethod() {
> > > > > > > > > > > > > > > > > >> > >>    Map<String, String> myRetval =
> > > > > > > > > > > > > > > > > getUnmodifiableSaslExtensionsMap();
> > > > > > > > > > > > > > > > > >> > >>    return () -> myRetval;
> > > > > > > > > > > > > > > > > >> > >> }
> > > > > > > > > > > > > > > > > >> > >>
> > > > > > > > > > > > > > > > > >> > >> I think the main reason for making
> > > > > > > SaslExtensions
> > > > > > > > > > part
> > > > > > > > > > > of
> > > > > > > > > > > > > the
> > > > > > > > > > > > > > > > > public
> > > > > > > > > > > > > > > > > >> > >> interface is to avoid adding a Map
> to
> > > the
> > > > > > > > Subject's
> > > > > > > > > > > > public
> > > > > > > > > > > > > > > > > >> credentials.
> > > > > > > > > > > > > > > > > >> > >> Making SaslExtensions an interface
> > > meets
> > > > > that
> > > > > > > > > > > requirement
> > > > > > > > > > > > > and
> > > > > > > > > > > > > > > > then
> > > > > > > > > > > > > > > > > >> > allows
> > > > > > > > > > > > > > > > > >> > >> us to be free to implement whatever
> > we
> > > > want
> > > > > > > > > > internally.
> > > > > > > > > > > > > > > > > >> > >>
> > > > > > > > > > > > > > > > > >> > >> Thoughts?
> > > > > > > > > > > > > > > > > >> > >>
> > > > > > > > > > > > > > > > > >> > >> Ron
> > > > > > > > > > > > > > > > > >> > >>
> > > > > > > > > > > > > > > > > >> > >>> On Sun, Jul 22, 2018 at 12:45 PM
> Ron
> > > > > > > Dagostino <
> > > > > > > > > > > > > > > > rndg...@gmail.com
> > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > >> > wrote:
> > > > > > > > > > > > > > > > > >> > >>>
> > > > > > > > > > > > > > > > > >> > >>> Hi Rajini.  The SaslServer is
> going
> > to
> > > > > have
> > > > > > to
> > > > > > > > > > > validate
> > > > > > > > > > > > > the
> > > > > > > > > > > > > > > > > >> extensions,
> > > > > > > > > > > > > > > > > >> > >>> too, but I’m okay with keeping the
> > > > > > validation
> > > > > > > > > logic
> > > > > > > > > > > > > > elsewhere
> > > > > > > > > > > > > > > as
> > > > > > > > > > > > > > > > > >> long
> > > > > > > > > > > > > > > > > >> > as
> > > > > > > > > > > > > > > > > >> > >> it
> > > > > > > > > > > > > > > > > >> > >>> can be reused in both the client
> and
> > > the
> > > > > > > secret.
> > > > > > > > > > > > > > > > > >> > >>>
> > > > > > > > > > > > > > > > > >> > >>> I strongly prefer exposing a map()
> > > > method
> > > > > as
> > > > > > > > > opposed
> > > > > > > > > > > to
> > > > > > > > > > > > > > > > > >> > extensionNames()
> > > > > > > > > > > > > > > > > >> > >>> and extensionValue(String)
> methods.
> > It
> > > > is
> > > > > a
> > > > > > > > > smaller
> > > > > > > > > > > API
> > > > > > > > > > > > (2
> > > > > > > > > > > > > > > > methods
> > > > > > > > > > > > > > > > > >> > >> instead
> > > > > > > > > > > > > > > > > >> > >>> of 1), and it gives clients of the
> > API
> > > > > full
> > > > > > > > > > > map-related
> > > > > > > > > > > > > > > > > >> functionality
> > > > > > > > > > > > > > > > > >> > >>> (there’s a lot of support for
> > dealing
> > > > with
> > > > > > > maps
> > > > > > > > > in a
> > > > > > > > > > > > > variety
> > > > > > > > > > > > > > > of
> > > > > > > > > > > > > > > > > >> ways).
> > > > > > > > > > > > > > > > > >> > >>>
> > > > > > > > > > > > > > > > > >> > >>> Regardless of whether we go with a
> > > map()
> > > > > > > method
> > > > > > > > or
> > > > > > > > > > > > > > > > > extensionNames()
> > > > > > > > > > > > > > > > > >> and
> > > > > > > > > > > > > > > > > >> > >>> extensionValue(String) methods,
> the
> > > > > > semantics
> > > > > > > of
> > > > > > > > > > > > > mutability
> > > > > > > > > > > > > > > need
> > > > > > > > > > > > > > > > > to
> > > > > > > > > > > > > > > > > >> be
> > > > > > > > > > > > > > > > > >> > >>> clear.  I think either way we
> should
> > > > never
> > > > > > > > share a
> > > > > > > > > > map
> > > > > > > > > > > > > that
> > > > > > > > > > > > > > > > anyone
> > > > > > > > > > > > > > > > > >> else
> > > > > > > > > > > > > > > > > >> > >>> could possibly mutate — either a
> map
> > > > that
> > > > > > > > someone
> > > > > > > > > > > gives
> > > > > > > > > > > > us
> > > > > > > > > > > > > > or
> > > > > > > > > > > > > > > a
> > > > > > > > > > > > > > > > > map
> > > > > > > > > > > > > > > > > >> > that
> > > > > > > > > > > > > > > > > >> > >> we
> > > > > > > > > > > > > > > > > >> > >>> might expose.
> > > > > > > > > > > > > > > > > >> > >>>
> > > > > > > > > > > > > > > > > >> > >>> Thoughts?
> > > > > > > > > > > > > > > > > >> > >>>
> > > > > > > > > > > > > > > > > >> > >>> Ron
> > > > > > > > > > > > > > > > > >> > >>>
> > > > > > > > > > > > > > > > > >> > >>>> On Jul 22, 2018, at 11:23 AM,
> > Rajini
> > > > > > Sivaram
> > > > > > > <
> > > > > > > > > > > > > > > > > >> rajinisiva...@gmail.com
> > > > > > > > > > > > > > > > > >> > >
> > > > > > > > > > > > > > > > > >> > >>> wrote:
> > > > > > > > > > > > > > > > > >> > >>>>
> > > > > > > > > > > > > > > > > >> > >>>> Hmm.... I think we need a much
> > > simpler
> > > > > > > > > > SaslExtensions
> > > > > > > > > > > > > class
> > > > > > > > > > > > > > > if
> > > > > > > > > > > > > > > > we
> > > > > > > > > > > > > > > > > >> are
> > > > > > > > > > > > > > > > > >> > >>>> making it part of the public API.
> > > > > > > > > > > > > > > > > >> > >>>>
> > > > > > > > > > > > > > > > > >> > >>>> 1. I don't see the point of
> > including
> > > > > > > separator
> > > > > > > > > > > > anywhere
> > > > > > > > > > > > > in
> > > > > > > > > > > > > > > > > >> > >>> SaslExtensions.
> > > > > > > > > > > > > > > > > >> > >>>> Extensions provide a map and we
> > > > propagate
> > > > > > the
> > > > > > > > map
> > > > > > > > > > > from
> > > > > > > > > > > > > > client
> > > > > > > > > > > > > > > > to
> > > > > > > > > > > > > > > > > >> > server
> > > > > > > > > > > > > > > > > >> > >>>> using the protocol associated
> with
> > > the
> > > > > > > > mechanism
> > > > > > > > > in
> > > > > > > > > > > > use.
> > > > > > > > > > > > > > The
> > > > > > > > > > > > > > > > > >> separator
> > > > > > > > > > > > > > > > > >> > >> is
> > > > > > > > > > > > > > > > > >> > >>>> not configurable and should not
> be
> > a
> > > > > > concern
> > > > > > > of
> > > > > > > > > the
> > > > > > > > > > > > > > > implementor
> > > > > > > > > > > > > > > > > of
> > > > > > > > > > > > > > > > > >> > >>>> SaslExtensionsCallback interface
> > that
> > > > > > > provides
> > > > > > > > an
> > > > > > > > > > > > > instance
> > > > > > > > > > > > > > of
> > > > > > > > > > > > > > > > > >> > >>> SaslExtensions
> > > > > > > > > > > > > > > > > >> > >>>> .
> > > > > > > > > > > > > > > > > >> > >>>>
> > > > > > > > > > > > > > > > > >> > >>>> 2. I agree with Ron that we need
> > > > > > > > > mechanism-specific
> > > > > > > > > > > > > > > validation
> > > > > > > > > > > > > > > > of
> > > > > > > > > > > > > > > > > >> the
> > > > > > > > > > > > > > > > > >> > >>>> values from SaslExtensions. But I
> > > think
> > > > > we
> > > > > > > > could
> > > > > > > > > do
> > > > > > > > > > > the
> > > > > > > > > > > > > > > > > validation
> > > > > > > > > > > > > > > > > >> in
> > > > > > > > > > > > > > > > > >> > >> the
> > > > > > > > > > > > > > > > > >> > >>>> appropriate `SaslClient`
> > > implementation
> > > > > of
> > > > > > > that
> > > > > > > > > > > > > mechanism.
> > > > > > > > > > > > > > > > > >> > >>>>
> > > > > > > > > > > > > > > > > >> > >>>> I think we could just have a very
> > > > simple
> > > > > > > > > extensions
> > > > > > > > > > > > class
> > > > > > > > > > > > > > and
> > > > > > > > > > > > > > > > > move
> > > > > > > > > > > > > > > > > >> > >>>> everything else to appropriate
> > > internal
> > > > > > > classes
> > > > > > > > > of
> > > > > > > > > > > the
> > > > > > > > > > > > > > > > mechanisms
> > > > > > > > > > > > > > > > > >> > using
> > > > > > > > > > > > > > > > > >> > >>>> extensions. What do you think?
> > > > > > > > > > > > > > > > > >> > >>>>
> > > > > > > > > > > > > > > > > >> > >>>> public class SaslExtensions {
> > > > > > > > > > > > > > > > > >> > >>>>   private final Map<String,
> String>
> > > > > > > > extensionMap;
> > > > > > > > > > > > > > > > > >> > >>>>
> > > > > > > > > > > > > > > > > >> > >>>>   public
> SaslExtensions(Map<String,
> > > > > String>
> > > > > > > > > > > > > extensionMap) {
> > > > > > > > > > > > > > > > > >> > >>>>       this.extensionMap =
> > > extensionMap;
> > > > > > > > > > > > > > > > > >> > >>>>   }
> > > > > > > > > > > > > > > > > >> > >>>>
> > > > > > > > > > > > > > > > > >> > >>>>   public String
> > extensionValue(String
> > > > > > name) {
> > > > > > > > > > > > > > > > > >> > >>>>       return
> > extensionMap.get(name);
> > > > > > > > > > > > > > > > > >> > >>>>   }
> > > > > > > > > > > > > > > > > >> > >>>>
> > > > > > > > > > > > > > > > > >> > >>>>   public Set<String>
> > > extensionNames() {
> > > > > > > > > > > > > > > > > >> > >>>>       return
> extensionMap.keySet();
> > > > > > > > > > > > > > > > > >> > >>>>   }
> > > > > > > > > > > > > > > > > >> > >>>> }
> > > > > > > > > > > > > > > > > >> > >>>>
> > > > > > > > > > > > > > > > > >> > >>>>
> > > > > > > > > > > > > > > > > >> > >>>>
> > > > > > > > > > > > > > > > > >> > >>>>> On Sat, Jul 21, 2018 at 9:01 PM,
> > Ron
> > > > > > > > Dagostino <
> > > > > > > > > > > > > > > > > rndg...@gmail.com
> > > > > > > > > > > > > > > > > >> >
> > > > > > > > > > > > > > > > > >> > >>> wrote:
> > > > > > > > > > > > > > > > > >> > >>>>>
> > > > > > > > > > > > > > > > > >> > >>>>> Hi Stanislav and Rajini.  If
> > > > > > SaslExtensions
> > > > > > > is
> > > > > > > > > > going
> > > > > > > > > > > > to
> > > > > > > > > > > > > > part
> > > > > > > > > > > > > > > > of
> > > > > > > > > > > > > > > > > >> the
> > > > > > > > > > > > > > > > > >> > >>> public
> > > > > > > > > > > > > > > > > >> > >>>>> API, then it occurred to me that
> > one
> > > > of
> > > > > > the
> > > > > > > > > > > > requirements
> > > > > > > > > > > > > > of
> > > > > > > > > > > > > > > > all
> > > > > > > > > > > > > > > > > >> SASL
> > > > > > > > > > > > > > > > > >> > >>>>> extensions is that the keys and
> > > values
> > > > > > need
> > > > > > > to
> > > > > > > > > > match
> > > > > > > > > > > > > > > > > >> > >> mechanism-specific
> > > > > > > > > > > > > > > > > >> > >>>>> regular expressions.  For
> example,
> > > RFC
> > > > > > 5802
> > > > > > > (
> > > > > > > > > > > > > > > > > >> > >>>>>
> > https://tools.ietf.org/html/rfc5802
> > > )
> > > > > > > > specifies
> > > > > > > > > > the
> > > > > > > > > > > > > > regular
> > > > > > > > > > > > > > > > > >> > >> expressions
> > > > > > > > > > > > > > > > > >> > >>> for
> > > > > > > > > > > > > > > > > >> > >>>>> the SCRAM-specific SASL
> > mechanisms,
> > > > and
> > > > > > RFC
> > > > > > > > > 7628 (
> > > > > > > > > > > > > > > > > >> > >>>>>
> > https://tools.ietf.org/html/rfc7628
> > > )
> > > > > > > > specifies
> > > > > > > > > > > > > different
> > > > > > > > > > > > > > > > > regular
> > > > > > > > > > > > > > > > > >> > >>>>> expressions for the OAUTHBEARER
> > SASL
> > > > > > > > > mechanism.  I
> > > > > > > > > > > am
> > > > > > > > > > > > > > > thinking
> > > > > > > > > > > > > > > > > the
> > > > > > > > > > > > > > > > > >> > >>>>> SaslExtensions class should
> > probably
> > > > > > > provide a
> > > > > > > > > way
> > > > > > > > > > > to
> > > > > > > > > > > > > make
> > > > > > > > > > > > > > > > sure
> > > > > > > > > > > > > > > > > >> the
> > > > > > > > > > > > > > > > > >> > >> keys
> > > > > > > > > > > > > > > > > >> > >>>>> and values match the appropriate
> > > > regular
> > > > > > > > > > > expressions.
> > > > > > > > > > > > > > What
> > > > > > > > > > > > > > > do
> > > > > > > > > > > > > > > > > you
> > > > > > > > > > > > > > > > > >> > >>> think of
> > > > > > > > > > > > > > > > > >> > >>>>> something along the lines of the
> > > below
> > > > > > > > > definition
> > > > > > > > > > > for
> > > > > > > > > > > > > the
> > > > > > > > > > > > > > > > > >> > >> SaslExtensions
> > > > > > > > > > > > > > > > > >> > >>>>> class?  It is missing Javadoc
> and
> > > > > > > > > > > > > > > > toString()/hashCode()/equals()
> > > > > > > > > > > > > > > > > >> > >>> methods,
> > > > > > > > > > > > > > > > > >> > >>>>> of course, but aside from that,
> do
> > > you
> > > > > > think
> > > > > > > > > this
> > > > > > > > > > is
> > > > > > > > > > > > > > > > sufficient
> > > > > > > > > > > > > > > > > >> and
> > > > > > > > > > > > > > > > > >> > >>>>> appropriate?
> > > > > > > > > > > > > > > > > >> > >>>>>
> > > > > > > > > > > > > > > > > >> > >>>>> Ron
> > > > > > > > > > > > > > > > > >> > >>>>>
> > > > > > > > > > > > > > > > > >> > >>>>> public class SaslExtensions {
> > > > > > > > > > > > > > > > > >> > >>>>>   private final Map<String,
> > String>
> > > > > > > > > extensionsMap;
> > > > > > > > > > > > > > > > > >> > >>>>>
> > > > > > > > > > > > > > > > > >> > >>>>>   public SaslExtensions(String
> > > mapStr,
> > > > > > > String
> > > > > > > > > > > > > > > > keyValueSeparator,
> > > > > > > > > > > > > > > > > >> > >> String
> > > > > > > > > > > > > > > > > >> > >>>>> elementSeparator,
> > > > > > > > > > > > > > > > > >> > >>>>>           Pattern
> > > > saslNameRegexPattern,
> > > > > > > > Pattern
> > > > > > > > > > > > > > > > > >> > >> saslValueRegexPattern)
> > > > > > > > > > > > > > > > > >> > >>> {
> > > > > > > > > > > > > > > > > >> > >>>>>
>  this(Utils.parseMap(mapStr,
> > > > > > > > > > keyValueSeparator,
> > > > > > > > > > > > > > > > > >> > >> elementSeparator),
> > > > > > > > > > > > > > > > > >> > >>>>> saslNameRegexPattern,
> > > > > > > saslValueRegexPattern);
> > > > > > > > > > > > > > > > > >> > >>>>>   }
> > > > > > > > > > > > > > > > > >> > >>>>>
> > > > > > > > > > > > > > > > > >> > >>>>>   public
> > SaslExtensions(Map<String,
> > > > > > String>
> > > > > > > > > > > > > extensionsMap,
> > > > > > > > > > > > > > > > > Pattern
> > > > > > > > > > > > > > > > > >> > >>>>> saslNameRegexPattern,
> > > > > > > > > > > > > > > > > >> > >>>>>           Pattern
> > > > > saslValueRegexPattern) {
> > > > > > > > > > > > > > > > > >> > >>>>>       Map<String, String>
> > > > sanitizedCopy
> > > > > =
> > > > > > > new
> > > > > > > > > > > > > > > > > >> > >>>>> HashMap<>(extensionsMap.size()
> );
> > > > > > > > > > > > > > > > > >> > >>>>>       for (Entry<String, String>
> > > > entry :
> > > > > > > > > > > > > > > > > >> extensionsMap.entrySet()) {
> > > > > > > > > > > > > > > > > >> > >>>>>           if
> > (!saslNameRegexPattern.
> > > > > > > > > > > > > > matcher(entry.getKey()).
> > > > > > > > > > > > > > > > > >> > matches()
> > > > > > > > > > > > > > > > > >> > >>>>>                   ||
> > > > > > > > > > > > > > > > > >> > >>>>>
> > > > > > > > > !saslValueRegexPattern.matcher(entry.getValue()).
> > > > > > > > > > > > > > matches())
> > > > > > > > > > > > > > > > > >> > >>>>>               throw new
> > > > > > > > > > > > > IllegalArgumentException("Invalid
> > > > > > > > > > > > > > > key
> > > > > > > > > > > > > > > > or
> > > > > > > > > > > > > > > > > >> > >>>>> value");
> > > > > > > > > > > > > > > > > >> > >>>>>
> > > >  sanitizedCopy.put(entry.getKe
> > > > > > y(),
> > > > > > > > > > > > > > > entry.getValue());
> > > > > > > > > > > > > > > > > >> > >>>>>       }
> > > > > > > > > > > > > > > > > >> > >>>>>       this.extensionsMap =
> > > > > > > > > > > > > > > > > >> > >>
> > > > Collections.unmodifiableMap(sanitizedCopy);
> > > > > > > > > > > > > > > > > >> > >>>>>   }
> > > > > > > > > > > > > > > > > >> > >>>>>
> > > > > > > > > > > > > > > > > >> > >>>>>   public Map<String, String>
> > map() {
> > > > > > > > > > > > > > > > > >> > >>>>>       return extensionsMap;
> > > > > > > > > > > > > > > > > >> > >>>>>   }
> > > > > > > > > > > > > > > > > >> > >>>>> }
> > > > > > > > > > > > > > > > > >> > >>>>>
> > > > > > > > > > > > > > > > > >> > >>>>> On Fri, Jul 20, 2018 at 12:49 PM
> > > > > Stanislav
> > > > > > > > > > > Kozlovski <
> > > > > > > > > > > > > > > > > >> > >>>>> stanis...@confluent.io>
> > > > > > > > > > > > > > > > > >> > >>>>> wrote:
> > > > > > > > > > > > > > > > > >> > >>>>>
> > > > > > > > > > > > > > > > > >> > >>>>>> Hi Ron,
> > > > > > > > > > > > > > > > > >> > >>>>>>
> > > > > > > > > > > > > > > > > >> > >>>>>> I saw that and decided that
> would
> > > be
> > > > > the
> > > > > > > best
> > > > > > > > > > > > approach.
> > > > > > > > > > > > > > The
> > > > > > > > > > > > > > > > > >> current
> > > > > > > > > > > > > > > > > >> > >>>>>> ScramExtensions implementation
> > > uses a
> > > > > Map
> > > > > > > in
> > > > > > > > > the
> > > > > > > > > > > > public
> > > > > > > > > > > > > > > > > >> credentials
> > > > > > > > > > > > > > > > > >> > >>> and I
> > > > > > > > > > > > > > > > > >> > >>>>>> thought I would follow
> convention
> > > > > rather
> > > > > > > than
> > > > > > > > > > > > introduce
> > > > > > > > > > > > > > my
> > > > > > > > > > > > > > > > own
> > > > > > > > > > > > > > > > > >> > thing,
> > > > > > > > > > > > > > > > > >> > >>> but
> > > > > > > > > > > > > > > > > >> > >>>>>> maybe this is best
> > > > > > > > > > > > > > > > > >> > >>>>>>
> > > > > > > > > > > > > > > > > >> > >>>>>>> On Fri, Jul 20, 2018 at 8:39
> AM
> > > Ron
> > > > > > > > Dagostino
> > > > > > > > > <
> > > > > > > > > > > > > > > > > >> rndg...@gmail.com>
> > > > > > > > > > > > > > > > > >> > >>> wrote:
> > > > > > > > > > > > > > > > > >> > >>>>>>>
> > > > > > > > > > > > > > > > > >> > >>>>>>> Hi Stanislav.  I'm wondering
> if
> > we
> > > > > > should
> > > > > > > > make
> > > > > > > > > > > > > > > > SaslExtensions
> > > > > > > > > > > > > > > > > >> part
> > > > > > > > > > > > > > > > > >> > >> of
> > > > > > > > > > > > > > > > > >> > >>>>> the
> > > > > > > > > > > > > > > > > >> > >>>>>>> public API.  I mentioned this
> in
> > > my
> > > > > > review
> > > > > > > > of
> > > > > > > > > > the
> > > > > > > > > > > > PR,
> > > > > > > > > > > > > > too
> > > > > > > > > > > > > > > > (and
> > > > > > > > > > > > > > > > > >> > >> tagged
> > > > > > > > > > > > > > > > > >> > >>>>>>> Rajini to get her input).  If
> we
> > > > add a
> > > > > > Map
> > > > > > > > to
> > > > > > > > > > the
> > > > > > > > > > > > > > > Subject's
> > > > > > > > > > > > > > > > > >> public
> > > > > > > > > > > > > > > > > >> > >>>>>>> credentials we are basically
> > > making
> > > > a
> > > > > > > public
> > > > > > > > > > > > > commitment
> > > > > > > > > > > > > > > that
> > > > > > > > > > > > > > > > > any
> > > > > > > > > > > > > > > > > >> > Map
> > > > > > > > > > > > > > > > > >> > >>>>>>> associated with the public
> > > > credentials
> > > > > > > > defines
> > > > > > > > > > the
> > > > > > > > > > > > > SASL
> > > > > > > > > > > > > > > > > >> extensions
> > > > > > > > > > > > > > > > > >> > >> and
> > > > > > > > > > > > > > > > > >> > >>>>> we
> > > > > > > > > > > > > > > > > >> > >>>>>>> can never add another instance
> > > > > > > implementing
> > > > > > > > > Map
> > > > > > > > > > to
> > > > > > > > > > > > the
> > > > > > > > > > > > > > > > public
> > > > > > > > > > > > > > > > > >> > >>>>>> credentials.
> > > > > > > > > > > > > > > > > >> > >>>>>>> That's a very big constraint
> we
> > > are
> > > > > > > > committing
> > > > > > > > > > to,
> > > > > > > > > > > > and
> > > > > > > > > > > > > > I'm
> > > > > > > > > > > > > > > > > >> > wondering
> > > > > > > > > > > > > > > > > >> > >>> if
> > > > > > > > > > > > > > > > > >> > >>>>>> we
> > > > > > > > > > > > > > > > > >> > >>>>>>> should make SaslExtensions
> > public
> > > > and
> > > > > > > attach
> > > > > > > > > an
> > > > > > > > > > > > > instance
> > > > > > > > > > > > > > > of
> > > > > > > > > > > > > > > > > >> that to
> > > > > > > > > > > > > > > > > >> > >>> the
> > > > > > > > > > > > > > > > > >> > >>>>>>> Subject's public credentials
> > > > instead.
> > > > > > > > > > > > > > > > > >> > >>>>>>>
> > > > > > > > > > > > > > > > > >> > >>>>>>> Ron
> > > > > > > > > > > > > > > > > >> > >>>>>>>
> > > > > > > > > > > > > > > > > >> > >>>>>>> On Thu, Jul 19, 2018 at 8:15
> PM
> > > > > > Stanislav
> > > > > > > > > > > Kozlovski
> > > > > > > > > > > > <
> > > > > > > > > > > > > > > > > >> > >>>>>>> stanis...@confluent.io>
> > > > > > > > > > > > > > > > > >> > >>>>>>> wrote:
> > > > > > > > > > > > > > > > > >> > >>>>>>>
> > > > > > > > > > > > > > > > > >> > >>>>>>>> I have updated the PR and KIP
> > to
> > > > > > address
> > > > > > > > the
> > > > > > > > > > > > comments
> > > > > > > > > > > > > > > made
> > > > > > > > > > > > > > > > so
> > > > > > > > > > > > > > > > > >> far.
> > > > > > > > > > > > > > > > > >> > >>>>>> Please
> > > > > > > > > > > > > > > > > >> > >>>>>>>> take another look at them and
> > > share
> > > > > > your
> > > > > > > > > > > thoughts.
> > > > > > > > > > > > > > > > > >> > >>>>>>>> KIP:
> > > > > > > > > > > > > > > > > >> > >>>>>>>>
> > > > > > > > > > > > > > > > > >> > >>>>>>>>
> > > > > > > > > > > > > > > > > >> > >>>>>>>
> > > > > > > > > > > > > > > > > >> > >>>>>> https://cwiki.apache.org/
> > > > > > > > > > > > confluence/display/KAFKA/KIP-
> > > > > > > > > > > > > > > > > >> > >>>>>
> > > > > > > > > 342%3A+Add+support+for+Custom+SASL+extensions+in+
> > > > > > > > > > > > > > > > > >> > >>>>> OAuthBearer+authentication
> > > > > > > > > > > > > > > > > >> > >>>>>>>> PR: Pull request <
> > > > > > > > > > > > > > > > https://github.com/apache/kafka/pull/5379>
> > > > > > > > > > > > > > > > > >> > >>>>>>>>
> > > > > > > > > > > > > > > > > >> > >>>>>>>> Best,
> > > > > > > > > > > > > > > > > >> > >>>>>>>> Stanislav
> > > > > > > > > > > > > > > > > >> > >>>>>>>>
> > > > > > > > > > > > > > > > > >> > >>>>>>>> On Thu, Jul 19, 2018 at 1:58
> PM
> > > > > > Stanislav
> > > > > > > > > > > > Kozlovski <
> > > > > > > > > > > > > > > > > >> > >>>>>>>> stanis...@confluent.io>
> > > > > > > > > > > > > > > > > >> > >>>>>>>> wrote:
> > > > > > > > > > > > > > > > > >> > >>>>>>>>
> > > > > > > > > > > > > > > > > >> > >>>>>>>>> Hi Ron,
> > > > > > > > > > > > > > > > > >> > >>>>>>>>>
> > > > > > > > > > > > > > > > > >> > >>>>>>>>> Agreed.
> > `SaslExtensionsCallback`
> > > > > will
> > > > > > be
> > > > > > > > the
> > > > > > > > > > > only
> > > > > > > > > > > > > > public
> > > > > > > > > > > > > > > > API
> > > > > > > > > > > > > > > > > >> > >>>>> addition
> > > > > > > > > > > > > > > > > >> > >>>>>>> and
> > > > > > > > > > > > > > > > > >> > >>>>>>>>> new documentation for the
> > > > extension
> > > > > > > > strings.
> > > > > > > > > > > > > > > > > >> > >>>>>>>>> A question that came up -
> > should
> > > > the
> > > > > > > > > > > > > > > LoginCallbackHandler
> > > > > > > > > > > > > > > > > >> throw
> > > > > > > > > > > > > > > > > >> > an
> > > > > > > > > > > > > > > > > >> > >>>>>>>>> exception or simply ignore
> > > > key/value
> > > > > > > > > extension
> > > > > > > > > > > > pairs
> > > > > > > > > > > > > > who
> > > > > > > > > > > > > > > > do
> > > > > > > > > > > > > > > > > >> not
> > > > > > > > > > > > > > > > > >> > >>>>> match
> > > > > > > > > > > > > > > > > >> > >>>>>>> the
> > > > > > > > > > > > > > > > > >> > >>>>>>>>> validation regex pattern? I
> > > guess
> > > > it
> > > > > > > would
> > > > > > > > > be
> > > > > > > > > > > > better
> > > > > > > > > > > > > > to
> > > > > > > > > > > > > > > > > >> throw, as
> > > > > > > > > > > > > > > > > >> > >>>>> to
> > > > > > > > > > > > > > > > > >> > >>>>>>>> avoid
> > > > > > > > > > > > > > > > > >> > >>>>>>>>> confusion.
> > > > > > > > > > > > > > > > > >> > >>>>>>>>>
> > > > > > > > > > > > > > > > > >> > >>>>>>>>> And yes, I will make sure
> the
> > > > > > key/value
> > > > > > > > are
> > > > > > > > > > > > > validated
> > > > > > > > > > > > > > on
> > > > > > > > > > > > > > > > the
> > > > > > > > > > > > > > > > > >> > >> client
> > > > > > > > > > > > > > > > > >> > >>>>>> as
> > > > > > > > > > > > > > > > > >> > >>>>>>>>> well as in the server. Even
> > > then,
> > > > I
> > > > > > > > > structured
> > > > > > > > > > > the
> > > > > > > > > > > > > > > > > >> > >>>>>>>> getNegotiatedProperty()
> > > > > > > > > > > > > > > > > >> > >>>>>>>>> method such that the
> > > > > OAUTHBEARER.token
> > > > > > > can
> > > > > > > > > > never
> > > > > > > > > > > > be
> > > > > > > > > > > > > > > > > >> overridden. I
> > > > > > > > > > > > > > > > > >> > >>>>>>>>> considered adding a test for
> > > that,
> > > > > > but I
> > > > > > > > > > figured
> > > > > > > > > > > > > > having
> > > > > > > > > > > > > > > > the
> > > > > > > > > > > > > > > > > >> regex
> > > > > > > > > > > > > > > > > >> > >>>>>>>>> validation be enough of a
> > > > guarantee.
> > > > > > > > > > > > > > > > > >> > >>>>>>>>>
> > > > > > > > > > > > > > > > > >> > >>>>>>>>> On Thu, Jul 19, 2018 at 9:49
> > AM
> > > > Ron
> > > > > > > > > Dagostino
> > > > > > > > > > <
> > > > > > > > > > > >
>

Reply via email to