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.getKey(), 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 <
> >> rndg...@gmail.com
> >> > >
> >> > >>>>>>> wrote:
> >> > >>>>>>>>>
> >> > >>>>>>>>>> Hi Rajini and Stanislav.  Rajini, yes, I think you are
> right
> >> > >> about
> >> > >>>>>> the
> >> > >>>>>>>>>> login callback handler being more appropriate for
> retrieving
> >> the
> >> > >>>>>> SASL
> >> > >>>>>>>>>> extensions than the login module itself (how many times am
> I
> >> > >> going
> >> > >>>>>> to
> >> > >>>>>>>> have
> >> > >>>>>>>>>> to be encouraged to leverage the callback handlers?!? lol).
> >> > >>>>>>>>>> OAuthBearerLoginModule should ask its login callback
> handler
> >> to
> >> > >>>>>> handle
> >> > >>>>>>>> an
> >> > >>>>>>>>>> instance of SaslExtensionsCallback in addition to an
> >> instance of
> >> > >>>>>>>>>> OAuthBearerTokenCallback, and the default login callback
> >> handler
> >> > >>>>>>>>>> implementation (OAuthBearerUnsecuredLoginCallbackHandler)
> >> > should
> >> > >>>>>>> either
> >> > >>>>>>>>>> return an empty map via callback or it should recognize
> >> > >> additional
> >> > >>>>>>> JAAS
> >> > >>>>>>>>>> module options of the form
> >> > >>>>>>> unsecuredLoginExtension_<extensionName>=value
> >> > >>>>>>>>>> so
> >> > >>>>>>>>>> that arbitrary extensions can be added in development and
> >> test
> >> > >>>>>>> scenarios
> >> > >>>>>>>>>> (similar to how arbitrary claims on unsecured tokens can be
> >> > >>>>> created
> >> > >>>>>> in
> >> > >>>>>>>>>> those scenarios via the JAAS module options
> >> > >>>>>>>>>> unsecuredLoginStringClaim_<claimName>=value, etc.).  Then
> the
> >> > >>>>>>>>>> OAuthBearerLoginModule can add a map of any extensions to
> the
> >> > >>>>>>> Subject's
> >> > >>>>>>>>>> public credentials where the default SASL client callback
> >> > handler
> >> > >>>>>>> class
> >> > >>>>>>>> (
> >> > >>>>>>>>>> OAuthBearerSaslClientCallbackHandler) can be amended to
> >> support
> >> > >>>>>>>>>> SaslExtensionsCallback and look on the Subject accordingly.
> >> > >> There
> >> > >>>>>>> would
> >> > >>>>>>>>>> be
> >> > >>>>>>>>>> no need to implement a custom sasl.client.callback.handler.
> >> > class
> >> > >>>>> in
> >> > >>>>>>> this
> >> > >>>>>>>>>> case, and no logic would need to be moved to a public
> static
> >> > >>>>> method
> >> > >>>>>> on
> >> > >>>>>>>>>> OAuthBearerLoginModule as I had proposed (at least not
> right
> >> > now,
> >> > >>>>>>> anyway
> >> > >>>>>>>>>> --
> >> > >>>>>>>>>> there may come a time when a need for a custom
> >> > >>>>>>>>>> sasl.client.callback.handler.class is identified, and at
> that
> >> > >>>>> point
> >> > >>>>>>> the
> >> > >>>>>>>>>> default implementation would either have to made part of
> the
> >> > >>>>> public
> >> > >>>>>>> API
> >> > >>>>>>>>>> with protected rather than private methods so it could be
> >> > >> directly
> >> > >>>>>>>>>> extended
> >> > >>>>>>>>>> or its logic would have to be moved to public static
> methods
> >> on
> >> > >>>>>>>>>> OAuthBearerLoginModule).
> >> > >>>>>>>>>>
> >> > >>>>>>>>>> So, to try to summarize, I think SaslExtensionsCallback
> will
> >> be
> >> > >>>>> the
> >> > >>>>>>> only
> >> > >>>>>>>>>> public API addition due to this KIP in terms of code, and
> >> then
> >> > >>>>> maybe
> >> > >>>>>>> the
> >> > >>>>>>>>>> recognition of the unsecuredLoginExtension_<
> >> > extensionName>=value
> >> > >>>>>>> module
> >> > >>>>>>>>>> options in the default unsecured case (which would be a
> >> > >>>>>> documentation
> >> > >>>>>>>>>> change and an internal implementation issue rather than a
> >> public
> >> > >>>>> API
> >> > >>>>>>> in
> >> > >>>>>>>>>> terms of code).  And then also the fact that extension
> names
> >> and
> >> > >>>>>>> values
> >> > >>>>>>>>>> are
> >> > >>>>>>>>>> accessed on the server side via negotiated properties.  Do
> I
> >> > have
> >> > >>>>>> that
> >> > >>>>>>>>>> summary right?
> >> > >>>>>>>>>>
> >> > >>>>>>>>>> One thing I want to note is that the code needs to make
> sure
> >> the
> >> > >>>>>>>> extension
> >> > >>>>>>>>>> names are composed of only ALPHA [a-zA-Z] characters as per
> >> the
> >> > >>>>> spec
> >> > >>>>>>>> (not
> >> > >>>>>>>>>> only for that reason, but to also make sure the token
> >> available
> >> > >> at
> >> > >>>>>> the
> >> > >>>>>>>>>> OAUTHBEARER.token negotiated property can't be
> overwritten).
> >> > >>>>>>>>>>
> >> > >>>>>>>>>> Ron
> >> > >>>>>>>>>>
> >> > >>>>>>>>>> On Thu, Jul 19, 2018 at 12:43 PM Stanislav Kozlovski <
> >> > >>>>>>>>>> stanis...@confluent.io>
> >> > >>>>>>>>>> wrote:
> >> > >>>>>>>>>>
> >> > >>>>>>>>>>> Hey Ron,
> >> > >>>>>>>>>>>
> >> > >>>>>>>>>>> Come to think of it, I think what Rajini said makes more
> >> sense
> >> > >>>>>> than
> >> > >>>>>>> my
> >> > >>>>>>>>>>> initial proposal. Having the
> >> OAuthBearerClientCallbackHandler
> >> > >>>>>>> populate
> >> > >>>>>>>>>>> SaslExtensionsCallback by taking a Map from the Subject
> >> would
> >> > >>>>> ease
> >> > >>>>>>>>>> users'
> >> > >>>>>>>>>>> implementation - they'd only have to provide a login
> >> callback
> >> > >>>>>>> handler
> >> > >>>>>>>>>> which
> >> > >>>>>>>>>>> attaches extensions to the Subject.
> >> > >>>>>>>>>>> I will now update the PR and the examples in the KIP. Let
> me
> >> > >>>>> know
> >> > >>>>>>> what
> >> > >>>>>>>>>> you
> >> > >>>>>>>>>>> think
> >> > >>>>>>>>>>>
> >> > >>>>>>>>>>> Hi Rajini,
> >> > >>>>>>>>>>> Yes, I will switch both classes to private/public as it
> >> makes
> >> > >>>>>> total
> >> > >>>>>>>>>> sense.
> >> > >>>>>>>>>>>
> >> > >>>>>>>>>>> Best,
> >> > >>>>>>>>>>> Stanislav
> >> > >>>>>>>>>>> On Thu, Jul 19, 2018 at 9:02 AM Rajini Sivaram <
> >> > >>>>>>>> rajinisiva...@gmail.com
> >> > >>>>>>>>>>>
> >> > >>>>>>>>>>> wrote:
> >> > >>>>>>>>>>>
> >> > >>>>>>>>>>>> Hi Stanislav,
> >> > >>>>>>>>>>>>
> >> > >>>>>>>>>>>> Thanks for the KIP. Since SaslExtensions will be an
> >> internal
> >> > >>>>>>> class,
> >> > >>>>>>>>>> can
> >> > >>>>>>>>>>> we
> >> > >>>>>>>>>>>> remove it from the KIP to avoid confusion? Also, can we
> add
> >> > >>>>> the
> >> > >>>>>>>>>> package
> >> > >>>>>>>>>>>> name for SaslExtensionsCallback? The PR has it in
> >> > >>>>>>>>>>>> org.apache.kafka.common.security which is an internal
> >> > >>>>> package.
> >> > >>>>>> As
> >> > >>>>>>> a
> >> > >>>>>>>>>>> public
> >> > >>>>>>>>>>>> class, it could be in
> >> org.apache.kafka.common.security.auth.
> >> > >>>>>>>>>>>>
> >> > >>>>>>>>>>>> Regards,
> >> > >>>>>>>>>>>>
> >> > >>>>>>>>>>>> Rajini
> >> > >>>>>>>>>>>>
> >> > >>>>>>>>>>>> On Thu, Jul 19, 2018 at 4:50 PM, Rajini Sivaram <
> >> > >>>>>>>>>> rajinisiva...@gmail.com
> >> > >>>>>>>>>>>>
> >> > >>>>>>>>>>>> wrote:
> >> > >>>>>>>>>>>>
> >> > >>>>>>>>>>>>> Hi Ron,
> >> > >>>>>>>>>>>>>
> >> > >>>>>>>>>>>>> Is there a reason why wouldn't want to provide
> extensions
> >> > >>>>>> using
> >> > >>>>>>> a
> >> > >>>>>>>>>> login
> >> > >>>>>>>>>>>>> callback handler in the same way as we inject tokens?
> The
> >> > >>>>>>> easiest
> >> > >>>>>>>>>> way
> >> > >>>>>>>>>>> to
> >> > >>>>>>>>>>>>> inject custom extensions would be using the JAAS config.
> >> So
> >> > >>>>> we
> >> > >>>>>>>> could
> >> > >>>>>>>>>>> have
> >> > >>>>>>>>>>>>> both OAuthBearerTokenCallback and SaslExtensionsCallback
> >> > >>>>>>>> processed
> >> > >>>>>>>>>> by
> >> > >>>>>>>>>>> a
> >> > >>>>>>>>>>>>> login callback handler. And the map returned by
> >> > >>>>>>>>>> SaslExtensionsCallback
> >> > >>>>>>>>>>>>> could be added to Subject by the default
> >> > >>>>>>>>>>>> OAuthBearerSaslClientCallbackHandler.
> >> > >>>>>>>>>>>>> Since OAuth users have to provide a login callback
> handler
> >> > >>>>>>> anyway,
> >> > >>>>>>>>>>>> wouldn't
> >> > >>>>>>>>>>>>> it be a better fit?
> >> > >>>>>>>>>>>>>
> >> > >>>>>>>>>>>>> Thank you,
> >> > >>>>>>>>>>>>>
> >> > >>>>>>>>>>>>> Rajini
> >> > >>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>
> >> > >>>>>>>>>>>>> On Thu, Jul 19, 2018 at 4:08 PM, Ron Dagostino <
> >> > >>>>>>> rndg...@gmail.com
> >> > >>>>>>>>>
> >> > >>>>>>>>>>>> wrote:
> >> > >>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>> Hi Stanislav.
> >> > >>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>> Implementers of a custom sasl.client.callback.handler.
> >> > >>>>> class
> >> > >>>>>>> must
> >> > >>>>>>>> be
> >> > >>>>>>>>>>> sure
> >> > >>>>>>>>>>>>>> to
> >> > >>>>>>>>>>>>>> provide the existing logic in
> >> > >>>>>>>>>>>>>> org.apache.kafka.common.security.oauthbearer.
> >> > >>>>> internals.OAuth
> >> > >>>>>>>>>>>>>> BearerSaslClientCallbackHandler
> >> > >>>>>>>>>>>>>> that handles instances of OAuthBearerTokenCallback (by
> >> > >>>>>>> retrieving
> >> > >>>>>>>>>> the
> >> > >>>>>>>>>>>>>> private credential from the Subject); a custom
> >> > >>>>> implementation
> >> > >>>>>>>> that
> >> > >>>>>>>>>>> fails
> >> > >>>>>>>>>>>>>> to
> >> > >>>>>>>>>>>>>> do this will not work, so the KIP should state this
> >> > >>>>>>> requirement.
> >> > >>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>> The question then arises: how should implementers
> provide
> >> > >>>>> the
> >> > >>>>>>>>>> existing
> >> > >>>>>>>>>>>>>> logic in the OAuthBearerSaslClientCallbackHandler
> class?
> >> > >>>>>> That
> >> > >>>>>>>>>> class
> >> > >>>>>>>>>>> is
> >> > >>>>>>>>>>>>>> not
> >> > >>>>>>>>>>>>>> part of the public API, and its
> >> > >>>>>>>>>>> handleCallback(OAuthBearerTokenCallback)
> >> > >>>>>>>>>>>>>> method, which implements the logic, is private anyway
> (so
> >> > >>>>>> even
> >> > >>>>>>> if
> >> > >>>>>>>>>>>> someone
> >> > >>>>>>>>>>>>>> took the risk of extending the non-API class the method
> >> > >>>>> would
> >> > >>>>>>>>>>> generally
> >> > >>>>>>>>>>>>>> not
> >> > >>>>>>>>>>>>>> be available in the subclass).  So as it stands right
> now
> >> > >>>>>>>>>> implementers
> >> > >>>>>>>>>>>> are
> >> > >>>>>>>>>>>>>> left to copy/paste that logic into their code.  A
> better
> >> > >>>>>>> solution
> >> > >>>>>>>>>>> might
> >> > >>>>>>>>>>>> be
> >> > >>>>>>>>>>>>>> to have the private method in
> >> > >>>>>>>> OAuthBearerSaslClientCallbackHandler
> >> > >>>>>>>>>>>>>> invoke a
> >> > >>>>>>>>>>>>>> public static method on the
> >> > >>>>>>>>>>>>>>
> >> > >>>>>>>> org.apache.kafka.common.security.oauthbearer.
> >> > OAuthBearerLoginModule
> >> > >>>>>>>>>>>> class
> >> > >>>>>>>>>>>>>> (which is part of the public API) to retrieve the
> >> > >>>>> credential
> >> > >>>>>>>> (e.g.
> >> > >>>>>>>>>>>> public
> >> > >>>>>>>>>>>>>> static OAuthBearerToken retrieveCredential(Subject)) .
> >> The
> >> > >>>>>>>>>> commit()
> >> > >>>>>>>>>>>>>> method
> >> > >>>>>>>>>>>>>> of the OAuthBearerLoginModule class is what puts the
> >> > >>>>>> credential
> >> > >>>>>>>>>> there
> >> > >>>>>>>>>>> in
> >> > >>>>>>>>>>>>>> the first place, so it could make sense for the class
> to
> >> > >>>>>> expose
> >> > >>>>>>>> the
> >> > >>>>>>>>>>>>>> complementary logic for retrieving the credential in
> this
> >> > >>>>>> way.
> >> > >>>>>>>>>>>> Regarding
> >> > >>>>>>>>>>>>>> your question about plugability of LoginModules, yes,
> the
> >> > >>>>>>>>>> LoginModule
> >> > >>>>>>>>>>>>>> class
> >> > >>>>>>>>>>>>>> is explicitly stated in the JAAS config, so it is
> indeed
> >> > >>>>>>>>>> pluggable; an
> >> > >>>>>>>>>>>>>> extending class would override the commit() method,
> call
> >> > >>>>>>>>>>> super.commit(),
> >> > >>>>>>>>>>>>>> and if the return value is true it would do whatever is
> >> > >>>>>>> necessary
> >> > >>>>>>>>>> to
> >> > >>>>>>>>>>> add
> >> > >>>>>>>>>>>>>> the desired SASL extensions to the Subject -- probably
> in
> >> > >>>>> the
> >> > >>>>>>>>>> public
> >> > >>>>>>>>>>>>>> credentials -- where a custom
> >> > >>>>>>> sasl.client.callback.handler.class
> >> > >>>>>>>>>> would
> >> > >>>>>>>>>>>> be
> >> > >>>>>>>>>>>>>> able to find them.  The KIP might state this, too.
> >> > >>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>> I'll look forward to seeing a new PR once the fix for
> the
> >> > >>>>>> 0x01
> >> > >>>>>>>>>>> separator
> >> > >>>>>>>>>>>>>> issue in the SASL/OAUTHBEARER implementation
> (KAFKA-7182
> >> > >>>>>>>>>>>>>> <
> >> > >>>>>>>
> https://issues.apache.org/jira/projects/KAFKA/issues/KAFKA-7182
> >> > >>>>>>>>> )
> >> > >>>>>>>>>> is
> >> > >>>>>>>>>>>>>> merged.
> >> > >>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>> Ron
> >> > >>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>> On Wed, Jul 18, 2018 at 6:38 PM Stanislav Kozlovski <
> >> > >>>>>>>>>>>>>> stanis...@confluent.io>
> >> > >>>>>>>>>>>>>> wrote:
> >> > >>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>> Hey Ron,
> >> > >>>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>> You brought up some great points. I did my best to
> >> > >>>>> address
> >> > >>>>>>> them
> >> > >>>>>>>>>> and
> >> > >>>>>>>>>>>>>> updated
> >> > >>>>>>>>>>>>>>> the KIP.
> >> > >>>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>> I should mention that I used commas to separate
> >> > >>>>> extensions
> >> > >>>>>> in
> >> > >>>>>>>> the
> >> > >>>>>>>>>>>>>> protocol,
> >> > >>>>>>>>>>>>>>> because we did not use the recommended Control-A
> >> > >>>>> character
> >> > >>>>>>> for
> >> > >>>>>>>>>>>>>> separators
> >> > >>>>>>>>>>>>>>> in the OAuth message and I figured I would not change
> >> it.
> >> > >>>>>>>>>>>>>>> Now that I saw your PR about implementing the proper
> >> > >>>>>>> separators
> >> > >>>>>>>>>> in
> >> > >>>>>>>>>>>> OAUTH
> >> > >>>>>>>>>>>>>>> <https://github.com/apache/kafka/pull/5391> and will
> >> > >>>>>> change
> >> > >>>>>>> my
> >> > >>>>>>>>>>>>>>> implementation once yours gets merged, meaning commas
> >> > >>>>> will
> >> > >>>>>>> be a
> >> > >>>>>>>>>>>>>> supported
> >> > >>>>>>>>>>>>>>> value for extensions.
> >> > >>>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>> About the implementation: yes you're right, you should
> >> > >>>>>>> define `
> >> > >>>>>>>>>>>>>>> sasl.client.callback.handler.class` which has the same
> >> > >>>>>>>>>> functionality
> >> > >>>>>>>>>>>>>> as `
> >> > >>>>>>>>>>>>>>> OAuthBearerSaslClientCallbackHandler` plus the
> >> > >>>>> additional
> >> > >>>>>>>>>>>>>> functionality of
> >> > >>>>>>>>>>>>>>> handling the `SaslExtensionsCallback` by attaching
> >> > >>>>>> extensions
> >> > >>>>>>>> to
> >> > >>>>>>>>>> it.
> >> > >>>>>>>>>>>>>>> The only reason you'd populate the `Subject` object
> with
> >> > >>>>>> the
> >> > >>>>>>>>>>>> extensions
> >> > >>>>>>>>>>>>>> is
> >> > >>>>>>>>>>>>>>> if you used the default `SaslClientCallbackHandler`
> >> > >>>>> (which
> >> > >>>>>>>>>> handles
> >> > >>>>>>>>>>> the
> >> > >>>>>>>>>>>>>>> extensions callback by adding whatever's in the
> >> subject),
> >> > >>>>>> as
> >> > >>>>>>>> the
> >> > >>>>>>>>>>> SCRAM
> >> > >>>>>>>>>>>>>>> authentication does.
> >> > >>>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>>
> >> > >>>>>> https://github.com/stanislavkozlovski/kafka/blob/KAFKA-7169-
> >> > >>>>>>>>>>>>>> custom-sasl-extensions/clients/src/main/java/org/
> >> > >>>>>>>>>>>>>> apache/kafka/common/security/
> >> > >>>>> oauthbearer/internals/OAuthBea
> >> > >>>>>>>>>>>>>> rerSaslClient.java#L92
> >> > >>>>>>>>>>>>>>> And yes, in that case you would need a custom
> >> > >>>>> `LoginModule`
> >> > >>>>>>>> which
> >> > >>>>>>>>>>>>>> populates
> >> > >>>>>>>>>>>>>>> the Subject in that case, although I'm not sure if
> Kafka
> >> > >>>>>>>> supports
> >> > >>>>>>>>>>>>>> pluggable
> >> > >>>>>>>>>>>>>>> LoginModules. Does it?
> >> > >>>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>> Best,
> >> > >>>>>>>>>>>>>>> Stanislav
> >> > >>>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>> On Wed, Jul 18, 2018 at 9:50 AM Ron Dagostino <
> >> > >>>>>>>> rndg...@gmail.com
> >> > >>>>>>>>>>>
> >> > >>>>>>>>>>>>>> wrote:
> >> > >>>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>>> Hi Stanislav.  Could you add something to the KIP
> about
> >> > >>>>>> the
> >> > >>>>>>>>>>> security
> >> > >>>>>>>>>>>>>>>> implications related to the CSV name/value pairs sent
> >> > >>>>> in
> >> > >>>>>>> the
> >> > >>>>>>>>>>>>>> extension?
> >> > >>>>>>>>>>>>>>>> For example, the OAuth access token may have a
> digital
> >> > >>>>>>>>>> signature,
> >> > >>>>>>>>>>>> but
> >> > >>>>>>>>>>>>>> the
> >> > >>>>>>>>>>>>>>>> extensions generally will not (unless one of the
> values
> >> > >>>>>> is
> >> > >>>>>>> a
> >> > >>>>>>>>>> JWS
> >> > >>>>>>>>>>>>>> compact
> >> > >>>>>>>>>>>>>>>> serialization, but I doubt anyone would go that far),
> >> > >>>>> so
> >> > >>>>>>> the
> >> > >>>>>>>>>>> server
> >> > >>>>>>>>>>>>>>>> generally cannot trust the extensions to be accurate
> >> > >>>>> for
> >> > >>>>>>>>>> anything
> >> > >>>>>>>>>>>>>>>> critical.  You mentioned the "better tracing and
> >> > >>>>>>>>>> troubleshooting"
> >> > >>>>>>>>>>>> use
> >> > >>>>>>>>>>>>>>> case,
> >> > >>>>>>>>>>>>>>>> which I think is fine despite the lack of security;
> >> > >>>>> given
> >> > >>>>>>>> that
> >> > >>>>>>>>>>> lack
> >> > >>>>>>>>>>>> of
> >> > >>>>>>>>>>>>>>>> security, though, I believe it is important to also
> >> > >>>>> state
> >> > >>>>>>>> what
> >> > >>>>>>>>>> the
> >> > >>>>>>>>>>>>>>>> extensions should *not* be used for.
> >> > >>>>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>>> Also, could you indicate in the KIP how the
> extensions
> >> > >>>>>>> might
> >> > >>>>>>>>>>>> actually
> >> > >>>>>>>>>>>>>> be
> >> > >>>>>>>>>>>>>>>> added?  My take on that would be to extend
> >> > >>>>>>>>>> OAuthBearerLoginModule
> >> > >>>>>>>>>>> to
> >> > >>>>>>>>>>>>>>>> override the initialize() and commit() methods so
> that
> >> > >>>>>> the
> >> > >>>>>>>>>> derived
> >> > >>>>>>>>>>>>>> class
> >> > >>>>>>>>>>>>>>>> would have access to the Subject instance and could
> >> > >>>>> add a
> >> > >>>>>>> map
> >> > >>>>>>>>>> to
> >> > >>>>>>>>>>> the
> >> > >>>>>>>>>>>>>>>> subject's public or private credentials when the
> commit
> >> > >>>>>>>>>> succeeds;
> >> > >>>>>>>>>>>>>> then I
> >> > >>>>>>>>>>>>>>>> think the sasl.client.callback.handler.class would
> >> > >>>>> have
> >> > >>>>>> to
> >> > >>>>>>> be
> >> > >>>>>>>>>>>>>> explicitly
> >> > >>>>>>>>>>>>>>>> set to a class that extends the default
> implementation
> >> > >>>>>>>>>>>>>>>> (OAuthBearerSaslClientCallbackHandler) and retrieves
> >> > >>>>> the
> >> > >>>>>>> map
> >> > >>>>>>>>>> when
> >> > >>>>>>>>>>>>>>> handling
> >> > >>>>>>>>>>>>>>>> the SaslExtensionsCallback.  But maybe you are
> thinking
> >> > >>>>>>> about
> >> > >>>>>>>>>> it
> >> > >>>>>>>>>>>>>>>> differently?  Some guidance on how to actually take
> >> > >>>>>>> advantage
> >> > >>>>>>>>>> of
> >> > >>>>>>>>>>> the
> >> > >>>>>>>>>>>>>>>> feature via an implementation would be a useful
> >> > >>>>> addition
> >> > >>>>>> to
> >> > >>>>>>>> the
> >> > >>>>>>>>>>> KIP.
> >> > >>>>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>>> Finally, I note that the extension parsing does not
> >> > >>>>>>> support a
> >> > >>>>>>>>>>> comma
> >> > >>>>>>>>>>>> in
> >> > >>>>>>>>>>>>>>> keys
> >> > >>>>>>>>>>>>>>>> or values.  This should be addressed somehow --
> either
> >> > >>>>> by
> >> > >>>>>>>>>>> supporting
> >> > >>>>>>>>>>>>>> via
> >> > >>>>>>>>>>>>>>> an
> >> > >>>>>>>>>>>>>>>> escaping mechanism or by explicitly acknowledging
> that
> >> > >>>>> it
> >> > >>>>>>> is
> >> > >>>>>>>>>>>>>> unsupported.
> >> > >>>>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>>> Thanks for the KIP and the simultaneous PR -- having
> >> > >>>>> both
> >> > >>>>>>> at
> >> > >>>>>>>>>> the
> >> > >>>>>>>>>>>> same
> >> > >>>>>>>>>>>>>>> time
> >> > >>>>>>>>>>>>>>>> really helped.
> >> > >>>>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>>> Ron
> >> > >>>>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>>> On Tue, Jul 17, 2018 at 6:22 PM Stanislav Kozlovski <
> >> > >>>>>>>>>>>>>>>> stanis...@confluent.io>
> >> > >>>>>>>>>>>>>>>> wrote:
> >> > >>>>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>>>> Hey group,
> >> > >>>>>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>>>> I just created a new KIP about adding customizable
> >> > >>>>> SASL
> >> > >>>>>>>>>>> extensions
> >> > >>>>>>>>>>>>>> to
> >> > >>>>>>>>>>>>>>> the
> >> > >>>>>>>>>>>>>>>>> OAuthBearer authentication mechanism. More details
> in
> >> > >>>>>> the
> >> > >>>>>>>>>>> proposal
> >> > >>>>>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>>>> KIP:
> >> > >>>>>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>>
> https://cwiki.apache.org/confluence/display/KAFKA/KIP-
> >> > >>>>> 342%
> >> > >>>>>>>>>>>>>>
> >> > >>>>>>>>>>>
> >> > >>>>>>>> 3A+Add+support+for+Custom+SASL+extensions+in+
> >> > >>>>> OAuthBearer+authentication
> >> > >>>>>>>>>>>>>>>>> JIRA: KAFKA-7169 <
> >> > >>>>>>>>>>>> https://issues.apache.org/jira/browse/KAFKA-7169>
> >> > >>>>>>>>>>>>>>>>> PR: Pull request <
> >> > >>>>>>>> https://github.com/apache/kafka/pull/5379>
> >> > >>>>>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>>>> --
> >> > >>>>>>>>>>>>>>>>> Best,
> >> > >>>>>>>>>>>>>>>>> Stanislav
> >> > >>>>>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>> --
> >> > >>>>>>>>>>>>>>> Best,
> >> > >>>>>>>>>>>>>>> Stanislav
> >> > >>>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>
> >> > >>>>>>>>>>>>>
> >> > >>>>>>>>>>>>
> >> > >>>>>>>>>>>
> >> > >>>>>>>>>>>
> >> > >>>>>>>>>>> --
> >> > >>>>>>>>>>> Best,
> >> > >>>>>>>>>>> Stanislav
> >> > >>>>>>>>>>>
> >> > >>>>>>>>>>
> >> > >>>>>>>>>
> >> > >>>>>>>>>
> >> > >>>>>>>>> --
> >> > >>>>>>>>> Best,
> >> > >>>>>>>>> Stanislav
> >> > >>>>>>>>>
> >> > >>>>>>>>
> >> > >>>>>>>>
> >> > >>>>>>>> --
> >> > >>>>>>>> Best,
> >> > >>>>>>>> Stanislav
> >> > >>>>>>>>
> >> > >>>>>>>
> >> > >>>>>>
> >> > >>>>>>
> >> > >>>>>> --
> >> > >>>>>> Best,
> >> > >>>>>> Stanislav
> >> > >>>>>>
> >> > >>>>>
> >> > >>>
> >> > >>
> >> > >
> >> > >
> >> > > --
> >> > > Best,
> >> > > Stanislav
> >> >
> >>
> >
>


-- 
Best,
Stanislav

Reply via email to