anmolnar commented on a change in pull request #3934:
URL: https://github.com/apache/hbase/pull/3934#discussion_r778084206



##########
File path: 
hbase-common/src/main/java/org/apache/hadoop/hbase/security/oauthbearer/internals/knox/OAuthBearerSignedJwtValidatorCallbackHandler.java
##########
@@ -0,0 +1,205 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.security.oauthbearer.internals.knox;
+
+import static 
org.apache.hadoop.hbase.security.token.OAuthBearerTokenUtil.OAUTHBEARER_MECHANISM;
+import com.nimbusds.jose.jwk.JWKSet;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.text.ParseException;
+import java.util.Map;
+import java.util.Objects;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.security.auth.AuthenticateCallbackHandler;
+import 
org.apache.hadoop.hbase.security.oauthbearer.OAuthBearerExtensionsValidatorCallback;
+import 
org.apache.hadoop.hbase.security.oauthbearer.OAuthBearerValidatorCallback;
+import org.apache.hadoop.hbase.security.oauthbearer.Utils;
+import org.apache.yetus.audience.InterfaceAudience;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A {@code CallbackHandler} that recognizes
+ * {@link OAuthBearerValidatorCallback} and validates a secure (signed) OAuth 2
+ * bearer token (JWT).
+ *
+ * It requires a valid JWK Set to be initialized at startup which holds the 
available
+ * RSA public keys that JWT signature can be validated with. The Set can be 
initialized
+ * via an URL or a local file.
+ *
+ * It requires there to be an <code>"exp" (Expiration Time)</code>
+ * claim of type Number. If <code>"iat" (Issued At)</code> or
+ * <code>"nbf" (Not Before)</code> claims are present each must be a number 
that
+ * precedes the Expiration Time claim, and if both are present the Not Before
+ * claim must not precede the Issued At claim. It also accepts the following
+ * options, none of which are required:
+ * <ul>
+ * <li>{@code hbase.security.oauth.jwt.jwks.url} set to a non-empty value if 
you
+ * wish to initialize the JWK Set via an URL. HTTPS URLs must have valid 
certificates.
+ * </li>
+ * <li>{@code hbase.security.oauth.jwt.jwks.file} set to a non-empty value if 
you
+ * wish to initialize the JWK Set from a local JSON file.
+ * </li>
+ * <li>{@code hbase.security.oauth.jwt.audience} set to a String value which
+ * you want the desired audience ("aud") the JWT to have.</li>
+ * <li>{@code hbase.security.oauth.jwt.issuer} set to a String value which
+ * you want the issuer ("iss") of the JWT has to be.</li>
+ * <li>{@code hbase.security.oauth.jwt.allowableclockskewseconds} set to a 
positive integer
+ * value if you wish to allow up to some number of positive seconds of
+ * clock skew (the default is 0)</li>
+ * </ul>
+ *
+ * It also recognizes {@link OAuthBearerExtensionsValidatorCallback} and 
validates
+ * every extension passed to it.
+ *
+ * This class is based on Kafka's OAuthBearerUnsecuredValidatorCallbackHandler.
+ */
[email protected]
+public class OAuthBearerSignedJwtValidatorCallbackHandler implements 
AuthenticateCallbackHandler {
+  private static final Logger LOG =
+    
LoggerFactory.getLogger(OAuthBearerSignedJwtValidatorCallbackHandler.class);
+  private static final String OPTION_PREFIX = "hbase.security.oauth.jwt.";
+  private static final String JWKS_URL = OPTION_PREFIX + "jwks.url";
+  private static final String JWKS_FILE = OPTION_PREFIX + "jwks.file";
+  private static final String ALLOWABLE_CLOCK_SKEW_SECONDS_OPTION =
+    OPTION_PREFIX + "allowableclockskewseconds";
+  static final String REQUIRED_AUDIENCE_OPTION = OPTION_PREFIX + "audience";
+  static final String REQUIRED_ISSUER_OPTION = OPTION_PREFIX + "issuer";
+  private Configuration hBaseConfiguration;
+  private JWKSet jwkSet;
+  private boolean configured = false;
+
+  @Override
+  public void handle(Callback[] callbacks) throws UnsupportedCallbackException 
{
+    if (!configured) {
+      throw new RuntimeException(
+        "OAuthBearerSignedJwtValidatorCallbackHandler handler be configured 
first.");
+    }

Review comment:
       In this case checking the `jwkSet` would be enough. I was thinking of 
this initialization thing a lot and doesn't have a strong opinion. Kafka 
follows this "configured" pattern pretty much everywhere and I'm not sure if 
there's convention in HBase for this.
   
   Addig a constructor and expecting that `jwkSet` is built by the instantiator 
would also be an option.
   
   What would you recommend?
   




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to