Hi,

I've written up an initial implementation of what has been discussed. Take
a look at it here: https://github.com/apache/kafka/pull/5497/
I will make sure to update the KIP once a review of the PR passes


On Mon, Aug 13, 2018 at 10:19 AM Rajini Sivaram <rajinisiva...@gmail.com>
wrote:

> Hi Stanislav,
>
> I think `token` and `extensions` on
> `OAuthBearerExtensionsValidatorCallback`
> should be immutable. The getters should return whatever was provided in the
> constructor and these should be stored as `final` objects. The whole point
> of separating out `OAuthBearerExtensionsValidatorCallback` from
> `OAuthBearerValidatorCallback`
> was to ensure that tokens are securely validated and created without any
> reference to insecure extensions. So it is critical that
> `OAuthBearerSaslServer` never uses the token returned by the extensions
> callback. As for the extensions, we should have two methods -
> {`extensions()`, `validatedExtensions()`} as I suggested in the last note
> OR {`defaultExtensions()`, `extensions()`} as used in NameCallback. I don't
> think we should make extensions mutable to use the same value for input and
> output. Btw, on error, we shouldn't care about the values in the returned
> extensions at all, we should simply fail authentication.
>
>
> On Sat, Aug 11, 2018 at 1:21 PM, Stanislav Kozlovski <
> stanis...@confluent.io
> > wrote:
>
> > Hi,
> >
> > @Ron
> > Agreed, tracking multiple errors would be better and would help diagnose
> > bad extensions faster
> > I've updated the KIP to address your two comments.
> > Regarding the Javadoc, please read below:
> >
> > @Rajini
> > The idea of the potentially-null token and extensions is not that they
> can
> > be passed to the constructor - it is that they can be nullified on a
> > validation error occurring (like it is done in the #error() method on
> > `OAuthBearerValidatorCallback`). Maybe it doesn't make too much sense to
> > nullify the token, but I believe it is worth it to do the same with the
> > extensions.
> >
> > I agree that the callback handler should himself populate the callback
> with
> > the *validated* extensions only. Will change implementation and KIP in
> due
> > time.
> >
> > Please share what you think about nullifying token/extensions on
> validation
> > error.
> >
> > Best,
> > Stanislav
> >
> >
> > On Fri, Aug 10, 2018 at 7:24 PM Rajini Sivaram <rajinisiva...@gmail.com>
> > wrote:
> >
> > > Hi Stanislav,
> > >
> > > For the point that Ron made above for:
> > >
> > > public OAuthBearerExtensionsValidatorCallback(OAuthBearerToken token,
> > > SaslExtensions
> > > extensions)
> > >
> > >
> > > I don't think we should ever invoke extensions callback without the
> > token.
> > > We can first validate the token and invoke extensions callback only if
> > > token is non-null. Can we clarify that in the javadoc?
> > >
> > >    - public SaslExtensions extensions() : Extensions should be non-null
> > >    - public OAuthBearerToken token() : Token should be non-null
> > >
> > >
> > > Also agree with Ron that we should have the ability to return errors
> for
> > > all invalid extensions, even if a callback handler may choose to stop
> on
> > > first failure.
> > >
> > > I think we also need another method to return the extensions that were
> > > validated and will be made available as negotiated properties. As per
> the
> > > RFC, server should ignore unknown extensions. So callback handlers need
> > to
> > > be able to validate the ones they know of and return those. Other
> > > extensions should not be added to the SaslServer's negotiated
> properties.
> > >
> > >    - public SaslExtensions validatedExtensions()
> > >
> > >
> > >
> > > On Fri, Aug 10, 2018 at 3:26 PM, Ron Dagostino <rndg...@gmail.com>
> > wrote:
> > >
> > > > Hi Stanislav.  Here are a few KIP comments.
> > > >
> > > > <<<There are also additional regex validations for extension name and
> > > > values to ensure they conform to the OAuth standard
> > > > It is the SASL/OAUTHBEARER standard that defines the regular
> > expressions
> > > > (specifically, https://tools.ietf.org/html/rfc7628#section-3.1)
> rather
> > > > than
> > > > any of the OAuth specifications.  It would be good to make this
> > > > clarification.
> > > >
> > > > <<<public OAuthBearerExtensionsValidatorCallback(OAuthBearerToken
> > token,
> > > > SaslExtensions extensions)
> > > > This constructor lacks Javadoc in the KIP.  Could you add it, and
> also
> > > > indicate which of the two parameters are required vs. optional?  The
> > > > Javadoc for the token() method indicates that the return value could
> be
> > > > null, but that would only be true if the constructor accepted a null
> > > value
> > > > for the token.  I'm okay with the constructor accepting a null token
> > > > (Rajini, you may differ in opinion, in which case I defer to your
> > > > preference).  But please do clarify this issue.
> > > >
> > > > I also am not sure if exposing just one invalid extension name and
> > error
> > > > message in the OAuthBearerExtensionsValidatorCallback class is good
> > > > enough.  An alternative to invalidExtensionName() and errorMessage()
> > > > methods would be to return an always non-null but potentially empty
> > > > Map<String, String> so that potentially all of the provided
> extensions
> > > > could be validated and the list of invalid extension names could be
> > > > returned (along with the error message for each of them).  If we
> > adopted
> > > > this alternative then the error(String invalidExtensionName, String
> > > > errorMessage) method might need to be renamed addError(String
> > > > invalidExtensionName, String errorMessage).  I suspect it would be
> > better
> > > > to go with the map approach to support returning multiple error
> > messages
> > > > even if the default unsecured token validator implementation only
> adds
> > > the
> > > > first invalid extension name -- at least it would allow others to be
> > more
> > > > complete if they wish.  It might also be worth discussing whether a
> has
> > > > Error() method would be appropriate to add (returning true if the map
> > is
> > > > non-empty).  I don't have a strong preference on the issue of
> > supporting
> > > 1
> > > > vs. multiple errors (though I lean slightly towards supporting
> multiple
> > > > errors).  I defer to the preference of others in this regard.
> > > >
> > > > Finally, now that we are actually validating extensions, the comment
> > that
> > > > "An attempt to use [auth] will result in an exception" might cause
> > > > confusion and perhaps needs to be clarified to state that the
> exception
> > > > occurs on the client side before the extensions are sent to the
> server
> > > > rather than during extension validation on the server side (e.g. "An
> > > > attempt to send [auth] will result in an exception on the client").
> > > >
> > > > Ron
> > > >
> > > >
> > > > On Fri, Aug 10, 2018 at 7:22 AM Stanislav Kozlovski <
> > > > stanis...@confluent.io>
> > > > wrote:
> > > >
> > > > > Hi Rajini, Ron
> > > > >
> > > > > I've updated the KIP with the latest changes following our
> > discussion.
> > > > > Please do give it a read. If you feel it is alright, I will follow
> up
> > > > with
> > > > > a PR later.
> > > > >
> > > > > Best,
> > > > > Stanislav
> > > > >
> > > > > On Thu, Aug 9, 2018 at 10:09 AM Rajini Sivaram <
> > > rajinisiva...@gmail.com>
> > > > > wrote:
> > > > >
> > > > > > Hi Ron/Stansilav,
> > > > > >
> > > > > > OK, let's just go with 2. I think it would be better to add a
> > > > > > OAuth-specific extensions handler OAuthBearerExtensionsValidator
> > > > Callback
> > > > > > that
> > > > > > provides OAuthBearerToken.
> > > > > >
> > > > > > To summarise, we chose option 2 out of these four options:
> > > > > >
> > > > > >    1. {OAuthBearerValidatorCallback,
> SaslExtensionsValidatorCallbac
> > k}
> > > > :
> > > > > 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
> > > SaslExtensionValidationCallbac
> > > > k
> > > > > 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 OAuthBearerExtensionsValidator
> > > > Callback
> > > > > > > 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 =
> > > > > > > > > > > > > > > > > > > > > > > getUnmodifiableSaslExtensionsM
> > ap();
> > > > > > > > > > > > > > > > > > > > > > > >> > >>    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 =
> > > > > > > > > > > > > > > > > > > > > > > getUnmodifiableSaslExtensionsM
> > ap();
> > > > > > > > > > > > > > > > > > > > > > > >> > >>    return () ->
> myRetval;
> > > > > > > > > > > > > > > > > > > > > > > >> > >> }
> > > > > > > > > > > > > > > > > > > > > > > >> > >>
> > > > > > > > > > > > > > > > > > > > > > > >> > >> I think the main reason
> > for
> > > > > > making
> > > > > > > > > > > > > SaslExtensions
> > > > > > > > > > > > > > > > part
> > > > > > > > > > > > > > > > > of
> > > > > > > > > > > > > > > > > > > the
> > > >



-- 
Best,
Stanislav

Reply via email to