+1 (non-binding)

Thanks for the detailed KIP.

On Wed, May 16, 2018 at 5:59 PM, Mickael Maison <mickael.mai...@gmail.com>
wrote:

> Thanks for the KIP,
> +1 (non binding)
>
> On Wed, May 16, 2018 at 2:51 AM, Ron Dagostino <rndg...@gmail.com> wrote:
> > Hi Jun.  I think you are getting at the fact that OAuth 2 is a flexible
> > framework that allows different installations to do things differently.
> It
> > is true that the principal name in Kafka could come from any claim in the
> > token.  Most of the time it would come from the 'sub' claim, but it could
> > certainly come from another claim, or it could be only indirectly based
> on
> > a claim value (maybe certain text would be trimmed or prefixed/suffixed).
> > The point, which I think you are getting at, is that because the
> framework
> > is flexible we need to accommodate that flexibility.  The callback
> handler
> > class defined by the listener.name.sasl_ssl.oauthbearer.sasl.server.
> > callback.handler.class configuration value gives us the required
> > flexibility.  As an example, I have an implementation that leverages a
> > popular open source JOSE library to parse the compact serialization,
> > retrieve the public key if it has not yet been retrieved, verify the
> > digital signature, and map the 'sub' claim to the OAuthBearerToken's
> > principal name (which becomes the SASL authorization ID, which becomes
> the
> > Kafka principal name).  I could just as easily have mapped a different
> > claim to the OAuthBearerToken's principal name, manipulated the 'sub'
> claim
> > value in some way, etc.  I write the callback handler code, so I complete
> > flexibility to do whatever my OAuth 2 installation requires me to do.
> >
> > Ron
> >
> > On Tue, May 15, 2018 at 1:39 PM, Jun Rao <j...@confluent.io> wrote:
> >
> >> Hi, Ron,
> >>
> >> Thanks for the reply. I understood your answers to #2 and #3.
> >>
> >> For #1, will the server map all clients' principal name to the value
> >> associated with "sub" claim? How do we support mapping different
> clients to
> >> different principal names?
> >>
> >> Jun
> >>
> >> On Mon, May 14, 2018 at 7:02 PM, Ron Dagostino <rndg...@gmail.com>
> wrote:
> >>
> >> > Hi Jun.  Thanks for the +1 vote.
> >> >
> >> > Regarding the first question about token claims, yes, you have it
> correct
> >> > about translating the OAuth token to a principle name via a JAAS
> module
> >> > option in the default unsecured case.  Specifically, the OAuth SASL
> >> Server
> >> > implementation is responsible for setting the authorization ID, and it
> >> gets
> >> > the authorization ID from the OAuthBearerToken's principalName()
> method.
> >> > The listener.name.sasl_ssl.oauthbearer.sasl.server.
> >> callback.handler.class
> >> > is responsible for handling an instance of
> OAuthBearerValidatorCallback
> >> to
> >> > accept a token compact serialization from the client and return an
> >> instance
> >> > of OAuthBearerToken (assuming the compact serialization validates),
> and
> >> in
> >> > the default unsecured case the builtin unsecured validator callback
> >> handler
> >> > defines the OAuthBearerToken.principalName() method to return the
> 'sub'
> >> > claim value by default (with the actual claim it uses being
> configurable
> >> > via the unsecuredValidatorPrincipalClaimName JAAS module option).  So
> >> that
> >> > is how we translate from a token to a principal name in the default
> >> > unsecured (out-of-the-box) case.
> >> >
> >> > For production use cases, the implementation associated with
> >> > listener.name.sasl_ssl.oauthbearer.sasl.server.callback.handler.class
> >> can
> >> > do whatever it wants.  As an example, I have written a class that
> wraps a
> >> > com.nimbusds.jwt.SignedJWT instance (see
> >> > https://connect2id.com/products/nimbus-jose-jwt/) and presents it as
> an
> >> > OAuthBearerToken:
> >> >
> >> > public class NimbusSignedJwtOAuthBearerToken implements
> >> OAuthBearerToken {
> >> >     private final SignedJWT signedJwt;
> >> >     private final String principalName;
> >> >     private final Set<String> scope;
> >> >     private final Long startTimeMs;
> >> >     private final long lifetimeMs;
> >> >
> >> >     /**
> >> >      * Constructor
> >> >      *
> >> >      * @param signedJwt
> >> >      *            the mandatory signed JWT
> >> >      * @param principalClaimName
> >> >      *            the mandatory claim name identifying the claim from
> >> which
> >> > the
> >> >      *            principal name will be extracted. The claim must
> exist
> >> > and must be
> >> >      *            a String.
> >> >      * @param optionalScopeClaimName
> >> >      *            the optional claim name identifying the claim from
> >> which
> >> > any scope
> >> >      *            will be extracted. If specified and the claim exists
> >> then
> >> > the
> >> >      *            value must be either a String or a String List.
> >> >      * @throws ParseException
> >> >      *             if the principal claim does not exist or is not a
> >> > String; the
> >> >      *             scope claim is neither a String nor a String List;
> the
> >> > 'exp'
> >> >      *             claim does not exist or is not a number; the 'iat'
> >> claim
> >> > exists
> >> >      *             but is not a number; or the 'nbf' claim exists and
> is
> >> > not a
> >> >      *             number.
> >> >      */
> >> >     public NimbusSignedJwtOAuthBearerToken(SignedJWT signedJwt,
> String
> >> > principalClaimName,
> >> >             String optionalScopeClaimName) throws ParseException {
> >> >         // etc...
> >> >     }
> >> >
> >> > The callback handler runs the following code if the digital signature
> >> > validates:
> >> >
> >> >     callback.token(new NimbusSignedJwtOAuthBearerToken(signedJwt,
> "sub",
> >> > null));
> >> >
> >> > I hope that answers the first question.  If not let me know what I
> >> > missed/misunderstood and I'll be glad to try to address it.
> >> >
> >> > Regarding the second question, the classes OAuthBearerTokenCallback
> and
> >> > OAuthBearerValidatorCallback implement the Callback interface -- they
> are
> >> > the callbacks that the AuthenticateCallbackHandler implementations
> need
> >> to
> >> > handle.  Specifically, unless the unsecured functionality is what is
> >> > desired, the two configuration values [listener.name.sasl_ssl.
> >> oauthbearer.
> >> > ]sasl.login.callback.handler.class and
> >> > listener.name.sasl_ssl.oauthbearer.sasl.server.callback.handler.class
> >> > define the callback handlers that need to handle
> OAuthBearerTokenCallback
> >> > and OAuthBearerValidatorCallback, respectively.
> >> >
> >> > Regarding the third question, yes, I see your point that the way the
> spec
> >> > is worded could be taken to imply that the error code is a single
> >> > character: "A single ASCII..." (
> >> > https://tools.ietf.org/html/rfc6749#section-5.2).  However, it is
> not a
> >> > single character.  See the end of that section 5.2 for an example that
> >> > shows "error":"invalid_request" as the response.
> >> >
> >> > Thanks again for the +1 vote, Jun, and please do let me know if I can
> >> cover
> >> > anything else.
> >> >
> >> > Ron
> >> >
> >> >
> >> > On Mon, May 14, 2018 at 7:10 PM, Jun Rao <j...@confluent.io> wrote:
> >> >
> >> > > Hi, Ron,
> >> > >
> >> > > Thanks for the KIP. +1 from me. Just a few minor comments below.
> >> > >
> >> > > 1. It seems that we can translate an OAuth token to a principle name
> >> > > through the claim name configured in JASS. However, it's not clear
> to
> >> me
> >> > > how an OAuth token is mapped to a claim. Could you clarify that?
> >> > >
> >> > > 2. The wiki has the following code. It seems that
> >> > OAuthBearerTokenCallback
> >> > > should implement AuthenticateCallbackHandler? Ditto
> >> > > for OAuthBearerValidatorCallback.
> >> > >
> >> > > public class OAuthBearerTokenCallback implements Callback
> >> > >
> >> > > 3. In OAuthBearerTokenCallback, we have the following method. The
> OAuth
> >> > > spec says the error code is a single ASCII. So, should we return a
> Char
> >> > or
> >> > > a String?
> >> > >
> >> > > public String errorCode()
> >> > >
> >> > > Jun
> >> > >
> >> > >
> >> > > On Thu, May 3, 2018 at 8:55 PM, Ron Dagostino <rndg...@gmail.com>
> >> wrote:
> >> > >
> >> > > > Hi everyone.  I would like to start the vote for KIP-255:
> >> > > > https://cwiki.apache.org/confluence/pages/viewpage.
> >> > > action?pageId=75968876
> >> > > >
> >> > > > This KIP proposes to add the following functionality related to
> >> > > > SASL/OAUTHBEARER:
> >> > > >
> >> > > > 1) Allow clients (both brokers when SASL/OAUTHBEARER is the
> >> > inter-broker
> >> > > > protocol as well as non-broker clients) to flexibly retrieve an
> >> access
> >> > > > token from an OAuth 2 authorization server based on the
> declaration
> >> of
> >> > a
> >> > > > custom login CallbackHandler implementation and have that access
> >> token
> >> > > > transparently and automatically transmitted to a broker for
> >> > > authentication.
> >> > > >
> >> > > > 2) Allow brokers to flexibly validate provided access tokens when
> a
> >> > > client
> >> > > > establishes a connection based on the declaration of a custom SASL
> >> > Server
> >> > > > CallbackHandler implementation.
> >> > > >
> >> > > > 3) Provide implementations of the above retrieval and validation
> >> > features
> >> > > > based on an unsecured JSON Web Token that function out-of-the-box
> >> with
> >> > > > minimal configuration required (i.e. implementations of the two
> types
> >> > of
> >> > > > callback handlers mentioned above will be used by default with no
> >> need
> >> > to
> >> > > > explicitly declare them).
> >> > > >
> >> > > > 4) Allow clients (both brokers when SASL/OAUTHBEARER is the
> >> > inter-broker
> >> > > > protocol as well as non-broker clients) to transparently retrieve
> a
> >> new
> >> > > > access token in the background before the existing access token
> >> expires
> >> > > in
> >> > > > case the client has to open new connections.
> >> > > >
> >> > > > Thanks,
> >> > > >
> >> > > > Ron
> >> > > >
> >> > >
> >> >
> >>
>

Reply via email to