You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2017/10/04 14:56:32 UTC
camel git commit: CAMEL-11695: Add JWT algorithm param and polish
documentation
Repository: camel
Updated Branches:
refs/heads/master 5d8d3d201 -> a558f54ec
CAMEL-11695: Add JWT algorithm param and polish documentation
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/a558f54e
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/a558f54e
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/a558f54e
Branch: refs/heads/master
Commit: a558f54ec070e400167af366d3e973f806634760
Parents: 5d8d3d2
Author: Dmitry Volodin <dm...@gmail.com>
Authored: Wed Oct 4 16:39:54 2017 +0300
Committer: Claus Ibsen <da...@apache.org>
Committed: Wed Oct 4 16:55:20 2017 +0200
----------------------------------------------------------------------
.../src/main/docs/grpc-component.adoc | 6 +-
.../camel/component/grpc/GrpcAuthType.java | 2 +-
.../camel/component/grpc/GrpcConfiguration.java | 31 +++++--
.../camel/component/grpc/GrpcConsumer.java | 5 +-
.../camel/component/grpc/GrpcProducer.java | 6 +-
.../component/grpc/auth/jwt/JwtAlgorithm.java | 37 ++++++++
.../grpc/auth/jwt/JwtCallCredentials.java | 66 ++++++++++++++
.../component/grpc/auth/jwt/JwtHelper.java | 56 ++++++++++++
.../grpc/auth/jwt/JwtServerInterceptor.java | 88 ++++++++++++++++++
.../client/auth/jwt/JwtCallCredentials.java | 66 --------------
.../grpc/client/auth/jwt/JwtHelper.java | 43 ---------
.../server/auth/jwt/JwtServerInterceptor.java | 96 --------------------
.../grpc/GrpcConsumerSecurityTest.java | 9 +-
.../grpc/GrpcProducerSecurityTest.java | 5 +-
14 files changed, 290 insertions(+), 226 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/a558f54e/components/camel-grpc/src/main/docs/grpc-component.adoc
----------------------------------------------------------------------
diff --git a/components/camel-grpc/src/main/docs/grpc-component.adoc b/components/camel-grpc/src/main/docs/grpc-component.adoc
index d1252b1..2d76dd6 100644
--- a/components/camel-grpc/src/main/docs/grpc-component.adoc
+++ b/components/camel-grpc/src/main/docs/grpc-component.adoc
@@ -51,7 +51,7 @@ with the following path and query parameters:
| *service* | *Required* Fully qualified service name from the protocol buffer descriptor file (package dot service definition name) | | String
|===
-==== Query Parameters (24 parameters):
+==== Query Parameters (25 parameters):
[width="100%",cols="2,5,^1,2",options="header"]
|===
@@ -71,6 +71,7 @@ with the following path and query parameters:
| *userAgent* (producer) | The user agent header passed to the server | | String
| *synchronous* (advanced) | Sets whether synchronous processing should be strictly used or Camel is allowed to use asynchronous processing (if supported). | false | boolean
| *authenticationType* (security) | Authentication method type in advance to the SSL/TLS negotiation | NONE | GrpcAuthType
+| *jwtAlgorithm* (security) | JSON Web Token sign algorithm | HMAC256 | JwtAlgorithm
| *jwtIssuer* (security) | JSON Web Token issuer | | String
| *jwtSecret* (security) | JSON Web Token secret | | String
| *jwtSubject* (security) | JSON Web Token subject | | String
@@ -105,10 +106,13 @@ To enable these features the following component properties combinations must be
|||serviceAccountResource||Required
|3|*Custom JSON Web Token implementation authentication*|authenticationType|JWT|Required
|||negotiationType|NONE or TLS|Optional. The TLS/SSL not checking for this type, but strongly recommended.
+|||jwtAlgorithm|HMAC256(default) or (HMAC384,HMAC512)|Optional
|||jwtSecret||Required
|||jwtIssuer||Optional
|||jwtSubject||Optional
|=======================================================================
+TLS with OpenSSL is currently the recommended approach for using gRPC over TLS component.
+Using the JDK for ALPN is generally much slower and may not support the necessary ciphers for HTTP2. This function is not implemented in the component.
### gRPC producer resource type mapping
http://git-wip-us.apache.org/repos/asf/camel/blob/a558f54e/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/GrpcAuthType.java
----------------------------------------------------------------------
diff --git a/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/GrpcAuthType.java b/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/GrpcAuthType.java
index f76e5d8..e97735d 100644
--- a/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/GrpcAuthType.java
+++ b/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/GrpcAuthType.java
@@ -32,7 +32,7 @@ public enum GrpcAuthType {
GOOGLE,
/**
- * Custom JSON Web Token with HmacSHA256 algorithm implementation
+ * Custom JSON Web Token with HmacSHA algorithms implementation
*/
JWT
}
http://git-wip-us.apache.org/repos/asf/camel/blob/a558f54e/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/GrpcConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/GrpcConfiguration.java b/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/GrpcConfiguration.java
index 169dd6d..b2bb29a 100644
--- a/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/GrpcConfiguration.java
+++ b/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/GrpcConfiguration.java
@@ -22,6 +22,7 @@ import java.util.Map;
import io.grpc.internal.GrpcUtil;
import io.grpc.netty.NegotiationType;
import io.grpc.netty.NettyChannelBuilder;
+import org.apache.camel.component.grpc.auth.jwt.JwtAlgorithm;
import org.apache.camel.spi.Metadata;
import org.apache.camel.spi.UriParam;
import org.apache.camel.spi.UriParams;
@@ -51,8 +52,8 @@ public class GrpcConfiguration {
@UriParam(label = "security", defaultValue = "NONE")
private GrpcAuthType authenticationType = GrpcAuthType.NONE;
- @UriParam(label = "security")
- private String serviceAccountResource;
+ @UriParam(label = "security", defaultValue = "HMAC256")
+ private JwtAlgorithm jwtAlgorithm = JwtAlgorithm.HMAC256;
@UriParam(label = "security", secret = true)
private String jwtSecret;
@@ -64,6 +65,9 @@ public class GrpcConfiguration {
private String jwtSubject;
@UriParam(label = "security")
+ private String serviceAccountResource;
+
+ @UriParam(label = "security")
private String keyCertChainResource;
@UriParam(label = "security")
@@ -171,14 +175,14 @@ public class GrpcConfiguration {
}
/**
- * Service Account key file in JSON format resource link supported by the Google Cloud SDK
+ * JSON Web Token sign algorithm
*/
- public String getServiceAccountResource() {
- return serviceAccountResource;
+ public JwtAlgorithm getJwtAlgorithm() {
+ return jwtAlgorithm;
}
- public void setServiceAccountResource(String serviceAccountResource) {
- this.serviceAccountResource = serviceAccountResource;
+ public void setJwtAlgorithm(JwtAlgorithm jwtAlgorithm) {
+ this.jwtAlgorithm = jwtAlgorithm;
}
/**
@@ -213,6 +217,17 @@ public class GrpcConfiguration {
public void setJwtSubject(String jwtSubject) {
this.jwtSubject = jwtSubject;
}
+
+ /**
+ * Service Account key file in JSON format resource link supported by the Google Cloud SDK
+ */
+ public String getServiceAccountResource() {
+ return serviceAccountResource;
+ }
+
+ public void setServiceAccountResource(String serviceAccountResource) {
+ this.serviceAccountResource = serviceAccountResource;
+ }
/**
* The X.509 certificate chain file resource in PEM format link
@@ -373,5 +388,5 @@ public class GrpcConfiguration {
}
setService(uri.getPath().substring(1));
- }
+ }
}
http://git-wip-us.apache.org/repos/asf/camel/blob/a558f54e/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/GrpcConsumer.java
----------------------------------------------------------------------
diff --git a/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/GrpcConsumer.java b/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/GrpcConsumer.java
index 750ec21..dfe717f 100644
--- a/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/GrpcConsumer.java
+++ b/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/GrpcConsumer.java
@@ -34,9 +34,9 @@ import javassist.util.proxy.ProxyFactory;
import org.apache.camel.AsyncCallback;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
+import org.apache.camel.component.grpc.auth.jwt.JwtServerInterceptor;
import org.apache.camel.component.grpc.server.GrpcHeaderInterceptor;
import org.apache.camel.component.grpc.server.GrpcMethodHandler;
-import org.apache.camel.component.grpc.server.auth.jwt.JwtServerInterceptor;
import org.apache.camel.impl.DefaultConsumer;
import org.apache.camel.spi.ClassResolver;
import org.apache.camel.util.ObjectHelper;
@@ -129,7 +129,8 @@ public class GrpcConsumer extends DefaultConsumer {
if (configuration.getAuthenticationType() == GrpcAuthType.JWT) {
ObjectHelper.notNull(configuration.getJwtSecret(), "jwtSecret");
- serverBuilder = serverBuilder.intercept(new JwtServerInterceptor(configuration.getJwtSecret(), configuration.getJwtIssuer(), configuration.getJwtSubject()));
+ serverBuilder = serverBuilder.intercept(new JwtServerInterceptor(configuration.getJwtAlgorithm(), configuration.getJwtSecret(),
+ configuration.getJwtIssuer(), configuration.getJwtSubject()));
}
server = serverBuilder.addService(ServerInterceptors.intercept(bindableService, headerInterceptor))
http://git-wip-us.apache.org/repos/asf/camel/blob/a558f54e/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/GrpcProducer.java
----------------------------------------------------------------------
diff --git a/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/GrpcProducer.java b/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/GrpcProducer.java
index aa7fa37..a411f8e 100644
--- a/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/GrpcProducer.java
+++ b/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/GrpcProducer.java
@@ -30,12 +30,12 @@ import io.netty.handler.ssl.SslProvider;
import org.apache.camel.AsyncCallback;
import org.apache.camel.AsyncProcessor;
import org.apache.camel.Exchange;
+import org.apache.camel.component.grpc.auth.jwt.JwtCallCredentials;
+import org.apache.camel.component.grpc.auth.jwt.JwtHelper;
import org.apache.camel.component.grpc.client.GrpcExchangeForwarder;
import org.apache.camel.component.grpc.client.GrpcExchangeForwarderFactory;
import org.apache.camel.component.grpc.client.GrpcResponseAggregationStreamObserver;
import org.apache.camel.component.grpc.client.GrpcResponseRouterStreamObserver;
-import org.apache.camel.component.grpc.client.auth.jwt.JwtCallCredentials;
-import org.apache.camel.component.grpc.client.auth.jwt.JwtHelper;
import org.apache.camel.impl.DefaultProducer;
import org.apache.camel.spi.ClassResolver;
import org.apache.camel.util.ObjectHelper;
@@ -105,7 +105,7 @@ public class GrpcProducer extends DefaultProducer implements AsyncProcessor {
} else if (configuration.getAuthenticationType() == GrpcAuthType.JWT) {
ObjectHelper.notNull(configuration.getJwtSecret(), "jwtSecret");
- String jwtToken = JwtHelper.createJwtToken(configuration.getJwtSecret(), configuration.getJwtIssuer(), configuration.getJwtSubject());
+ String jwtToken = JwtHelper.createJwtToken(configuration.getJwtAlgorithm(), configuration.getJwtSecret(), configuration.getJwtIssuer(), configuration.getJwtSubject());
callCreds = new JwtCallCredentials(jwtToken);
}
http://git-wip-us.apache.org/repos/asf/camel/blob/a558f54e/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/auth/jwt/JwtAlgorithm.java
----------------------------------------------------------------------
diff --git a/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/auth/jwt/JwtAlgorithm.java b/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/auth/jwt/JwtAlgorithm.java
new file mode 100644
index 0000000..9a61545
--- /dev/null
+++ b/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/auth/jwt/JwtAlgorithm.java
@@ -0,0 +1,37 @@
+/**
+ * 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.camel.component.grpc.auth.jwt;
+
+/**
+ * Implemented JSON Web Token secret signing algorithms
+ */
+public enum JwtAlgorithm {
+ /**
+ * HmacSHA256 algorithm
+ */
+ HMAC256,
+
+ /**
+ * HmacSHA384 algorithm
+ */
+ HMAC384,
+
+ /**
+ * HmacSHA512 algorithm
+ */
+ HMAC512
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a558f54e/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/auth/jwt/JwtCallCredentials.java
----------------------------------------------------------------------
diff --git a/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/auth/jwt/JwtCallCredentials.java b/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/auth/jwt/JwtCallCredentials.java
new file mode 100644
index 0000000..490c237
--- /dev/null
+++ b/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/auth/jwt/JwtCallCredentials.java
@@ -0,0 +1,66 @@
+/**
+ * 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.camel.component.grpc.auth.jwt;
+
+import java.util.concurrent.Executor;
+
+import io.grpc.Attributes;
+import io.grpc.CallCredentials;
+import io.grpc.Metadata;
+import io.grpc.MethodDescriptor;
+import io.grpc.Status;
+import org.apache.camel.component.grpc.GrpcConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * JSON Web Token client credentials generator and injector
+ */
+public class JwtCallCredentials implements CallCredentials {
+ private static final Logger LOG = LoggerFactory.getLogger(JwtCallCredentials.class);
+ private final String jwtToken;
+
+ public JwtCallCredentials(String jwtToken) {
+ this.jwtToken = jwtToken;
+ }
+
+ @Override
+ public void applyRequestMetadata(MethodDescriptor<?, ?> method, Attributes attrs, Executor executor, MetadataApplier applier) {
+ String authority = attrs.get(ATTR_AUTHORITY);
+
+ LOG.debug("Using authority {} for credentials", authority);
+ executor.execute(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ LOG.debug("Start to apply for the JWT token header");
+ Metadata headers = new Metadata();
+ Metadata.Key<String> jwtKey = GrpcConstants.GRPC_JWT_METADATA_KEY;
+ headers.put(jwtKey, jwtToken);
+ applier.apply(headers);
+ } catch (Throwable e) {
+ LOG.debug("Unable to set metadata credentials header", e);
+ applier.fail(Status.UNAUTHENTICATED.withCause(e));
+ }
+ }
+ });
+ }
+
+ @Override
+ public void thisUsesUnstableApi() {
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a558f54e/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/auth/jwt/JwtHelper.java
----------------------------------------------------------------------
diff --git a/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/auth/jwt/JwtHelper.java b/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/auth/jwt/JwtHelper.java
new file mode 100644
index 0000000..bf2de48
--- /dev/null
+++ b/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/auth/jwt/JwtHelper.java
@@ -0,0 +1,56 @@
+/**
+ * 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.camel.component.grpc.auth.jwt;
+
+import java.io.UnsupportedEncodingException;
+
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.auth0.jwt.exceptions.JWTCreationException;
+
+/**
+ * JSON Web Token credentials generator helper
+ */
+public final class JwtHelper {
+ private JwtHelper() {
+ }
+
+ public static String createJwtToken(JwtAlgorithm algorithmName, String secret, String issuer, String subject) {
+ try {
+ Algorithm algorithm = selectAlgorithm(algorithmName, secret);
+ String token = JWT.create().withIssuer(issuer).withSubject(subject).sign(algorithm);
+ return token;
+ } catch (JWTCreationException e) {
+ throw new IllegalArgumentException("Unable to create JWT token", e);
+ } catch (UnsupportedEncodingException e) {
+ throw new IllegalArgumentException("UTF-8 encoding not supported during JWT token creation", e);
+ }
+ }
+
+ public static Algorithm selectAlgorithm(JwtAlgorithm algorithmName, String secret) throws IllegalArgumentException, UnsupportedEncodingException {
+ switch (algorithmName) {
+ case HMAC256:
+ return Algorithm.HMAC256(secret);
+ case HMAC384:
+ return Algorithm.HMAC384(secret);
+ case HMAC512:
+ return Algorithm.HMAC512(secret);
+ default:
+ throw new IllegalArgumentException("JWT algorithm " + algorithmName + " not implemented");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a558f54e/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/auth/jwt/JwtServerInterceptor.java
----------------------------------------------------------------------
diff --git a/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/auth/jwt/JwtServerInterceptor.java b/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/auth/jwt/JwtServerInterceptor.java
new file mode 100644
index 0000000..5186556
--- /dev/null
+++ b/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/auth/jwt/JwtServerInterceptor.java
@@ -0,0 +1,88 @@
+/**
+ * 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.camel.component.grpc.auth.jwt;
+
+import java.io.UnsupportedEncodingException;
+
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.JWTVerifier;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.auth0.jwt.exceptions.JWTCreationException;
+import com.auth0.jwt.interfaces.DecodedJWT;
+import io.grpc.Context;
+import io.grpc.Contexts;
+import io.grpc.Metadata;
+import io.grpc.ServerCall;
+import io.grpc.ServerCall.Listener;
+import io.grpc.ServerCallHandler;
+import io.grpc.ServerInterceptor;
+import io.grpc.Status;
+import org.apache.camel.component.grpc.GrpcConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * JSON Web Token credentials validator implementation
+ */
+public class JwtServerInterceptor implements ServerInterceptor {
+ private static final Logger LOG = LoggerFactory.getLogger(JwtServerInterceptor.class);
+
+ @SuppressWarnings("rawtypes")
+ private static final ServerCall.Listener NOOP_LISTENER = new ServerCall.Listener() {
+ };
+
+ private final JWTVerifier verifier;
+
+ public JwtServerInterceptor(JwtAlgorithm algorithm, String secret, String issuer, String subject) {
+ verifier = prepareJwtVerifier(algorithm, secret, issuer, subject);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <ReqT, RespT> Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata metadata, ServerCallHandler<ReqT, RespT> serverCallHandler) {
+ String jwtToken = metadata.get(GrpcConstants.GRPC_JWT_METADATA_KEY);
+ if (jwtToken == null) {
+ call.close(Status.UNAUTHENTICATED.withDescription("JWT Token is missing from metadata"), metadata);
+ return NOOP_LISTENER;
+ }
+
+ Context ctx;
+ try {
+ DecodedJWT verified = verifier.verify(jwtToken);
+ ctx = Context.current()
+ .withValue(GrpcConstants.GRPC_JWT_USER_ID_CTX_KEY, verified.getSubject() == null ? "anonymous" : verified.getSubject())
+ .withValue(GrpcConstants.GRPC_JWT_CTX_KEY, jwtToken);
+ } catch (Exception e) {
+ LOG.debug("JWT token verification failed - Unauthenticated");
+ call.close(Status.UNAUTHENTICATED.withDescription(e.getMessage()).withCause(e), metadata);
+ return NOOP_LISTENER;
+ }
+
+ return Contexts.interceptCall(ctx, call, metadata, serverCallHandler);
+ }
+
+ public static JWTVerifier prepareJwtVerifier(JwtAlgorithm algorithmName, String secret, String issuer, String subject) {
+ try {
+ Algorithm algorithm = JwtHelper.selectAlgorithm(algorithmName, secret);
+ return JWT.require(algorithm).withIssuer(issuer).withSubject(subject).build();
+ } catch (JWTCreationException e) {
+ throw new IllegalArgumentException("Unable to create JWT verifier", e);
+ } catch (UnsupportedEncodingException e) {
+ throw new IllegalArgumentException("UTF-8 encoding not supported during JWT verifier creation", e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/a558f54e/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/client/auth/jwt/JwtCallCredentials.java
----------------------------------------------------------------------
diff --git a/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/client/auth/jwt/JwtCallCredentials.java b/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/client/auth/jwt/JwtCallCredentials.java
deleted file mode 100644
index 676f284..0000000
--- a/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/client/auth/jwt/JwtCallCredentials.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * 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.camel.component.grpc.client.auth.jwt;
-
-import java.util.concurrent.Executor;
-
-import io.grpc.Attributes;
-import io.grpc.CallCredentials;
-import io.grpc.Metadata;
-import io.grpc.MethodDescriptor;
-import io.grpc.Status;
-import org.apache.camel.component.grpc.GrpcConstants;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * JSON Web Token client credentials generator and injector
- */
-public class JwtCallCredentials implements CallCredentials {
- private static final Logger LOG = LoggerFactory.getLogger(JwtCallCredentials.class);
- private final String jwtToken;
-
- public JwtCallCredentials(String jwtToken) {
- this.jwtToken = jwtToken;
- }
-
- @Override
- public void applyRequestMetadata(MethodDescriptor<?, ?> method, Attributes attrs, Executor executor, MetadataApplier applier) {
- String authority = attrs.get(ATTR_AUTHORITY);
-
- LOG.debug("Using authority {} for credentials", authority);
- executor.execute(new Runnable() {
- @Override
- public void run() {
- try {
- LOG.debug("Start to apply for the JWT token header");
- Metadata headers = new Metadata();
- Metadata.Key<String> jwtKey = GrpcConstants.GRPC_JWT_METADATA_KEY;
- headers.put(jwtKey, jwtToken);
- applier.apply(headers);
- } catch (Throwable e) {
- LOG.debug("Unable to set metadata credentials header", e);
- applier.fail(Status.UNAUTHENTICATED.withCause(e));
- }
- }
- });
- }
-
- @Override
- public void thisUsesUnstableApi() {
- }
-}
http://git-wip-us.apache.org/repos/asf/camel/blob/a558f54e/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/client/auth/jwt/JwtHelper.java
----------------------------------------------------------------------
diff --git a/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/client/auth/jwt/JwtHelper.java b/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/client/auth/jwt/JwtHelper.java
deleted file mode 100644
index d58f3a2..0000000
--- a/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/client/auth/jwt/JwtHelper.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * 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.camel.component.grpc.client.auth.jwt;
-
-import java.io.UnsupportedEncodingException;
-
-import com.auth0.jwt.JWT;
-import com.auth0.jwt.algorithms.Algorithm;
-import com.auth0.jwt.exceptions.JWTCreationException;
-
-/**
- * JSON Web Token credentials generator helper
- */
-public final class JwtHelper {
- private JwtHelper() {
- }
-
- public static String createJwtToken(String secret, String issuer, String subject) {
- try {
- Algorithm algorithm = Algorithm.HMAC256(secret);
- String token = JWT.create().withIssuer(issuer).withSubject(subject).sign(algorithm);
- return token;
- } catch (JWTCreationException e) {
- throw new IllegalArgumentException("Unable to create JWT token", e);
- } catch (UnsupportedEncodingException e) {
- throw new IllegalArgumentException("UTF-8 encoding not supported during JWT token creation", e);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/camel/blob/a558f54e/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/server/auth/jwt/JwtServerInterceptor.java
----------------------------------------------------------------------
diff --git a/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/server/auth/jwt/JwtServerInterceptor.java b/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/server/auth/jwt/JwtServerInterceptor.java
deleted file mode 100644
index f332b1e..0000000
--- a/components/camel-grpc/src/main/java/org/apache/camel/component/grpc/server/auth/jwt/JwtServerInterceptor.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/**
- * 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.camel.component.grpc.server.auth.jwt;
-
-import java.io.UnsupportedEncodingException;
-
-import com.auth0.jwt.JWT;
-import com.auth0.jwt.JWTVerifier;
-import com.auth0.jwt.algorithms.Algorithm;
-import com.auth0.jwt.exceptions.JWTCreationException;
-import com.auth0.jwt.interfaces.DecodedJWT;
-import io.grpc.Context;
-import io.grpc.Contexts;
-import io.grpc.Metadata;
-import io.grpc.ServerCall;
-import io.grpc.ServerCall.Listener;
-import io.grpc.ServerCallHandler;
-import io.grpc.ServerInterceptor;
-import io.grpc.Status;
-import org.apache.camel.component.grpc.GrpcConstants;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * JSON Web Token credentials validator implementation
- */
-public class JwtServerInterceptor implements ServerInterceptor {
- private static final Logger LOG = LoggerFactory.getLogger(JwtServerInterceptor.class);
-
- @SuppressWarnings("rawtypes")
- private static final ServerCall.Listener NOOP_LISTENER = new ServerCall.Listener() {
- };
-
- private final JWTVerifier verifier;
-
- public JwtServerInterceptor(String secret, String issuer, String subject) {
- verifier = JwtHelper.prepareJwtVerifier(secret, issuer, subject);
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public <ReqT, RespT> Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata metadata, ServerCallHandler<ReqT, RespT> serverCallHandler) {
- String jwtToken = metadata.get(GrpcConstants.GRPC_JWT_METADATA_KEY);
- if (jwtToken == null) {
- call.close(Status.UNAUTHENTICATED.withDescription("JWT Token is missing from metadata"), metadata);
- return NOOP_LISTENER;
- }
-
- Context ctx;
- try {
- DecodedJWT verified = verifier.verify(jwtToken);
- ctx = Context.current()
- .withValue(GrpcConstants.GRPC_JWT_USER_ID_CTX_KEY, verified.getSubject() == null ? "anonymous" : verified.getSubject())
- .withValue(GrpcConstants.GRPC_JWT_CTX_KEY, jwtToken);
- } catch (Exception e) {
- LOG.debug("JWT token verification failed - Unauthenticated");
- call.close(Status.UNAUTHENTICATED.withDescription(e.getMessage()).withCause(e), metadata);
- return NOOP_LISTENER;
- }
-
- return Contexts.interceptCall(ctx, call, metadata, serverCallHandler);
- }
-
- /**
- * JSON Web Token credentials validator helper
- */
- public static final class JwtHelper {
- private JwtHelper() {
- }
-
- public static JWTVerifier prepareJwtVerifier(String secret, String issuer, String subject) {
- try {
- Algorithm algorithm = Algorithm.HMAC256(secret);
- return JWT.require(algorithm).withIssuer(issuer).withSubject(subject).build();
- } catch (JWTCreationException e) {
- throw new IllegalArgumentException("Unable to create JWT verifier", e);
- } catch (UnsupportedEncodingException e) {
- throw new IllegalArgumentException("UTF-8 encoding not supported during JWT verifier creation", e);
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/camel/blob/a558f54e/components/camel-grpc/src/test/java/org/apache/camel/component/grpc/GrpcConsumerSecurityTest.java
----------------------------------------------------------------------
diff --git a/components/camel-grpc/src/test/java/org/apache/camel/component/grpc/GrpcConsumerSecurityTest.java b/components/camel-grpc/src/test/java/org/apache/camel/component/grpc/GrpcConsumerSecurityTest.java
index 9a89b9d..ee53b5d 100644
--- a/components/camel-grpc/src/test/java/org/apache/camel/component/grpc/GrpcConsumerSecurityTest.java
+++ b/components/camel-grpc/src/test/java/org/apache/camel/component/grpc/GrpcConsumerSecurityTest.java
@@ -28,8 +28,9 @@ import io.grpc.netty.NettyChannelBuilder;
import io.grpc.stub.StreamObserver;
import io.netty.handler.ssl.SslProvider;
import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.component.grpc.client.auth.jwt.JwtCallCredentials;
-import org.apache.camel.component.grpc.client.auth.jwt.JwtHelper;
+import org.apache.camel.component.grpc.auth.jwt.JwtAlgorithm;
+import org.apache.camel.component.grpc.auth.jwt.JwtCallCredentials;
+import org.apache.camel.component.grpc.auth.jwt.JwtHelper;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.AvailablePortFinder;
import org.apache.camel.test.junit4.CamelTestSupport;
@@ -62,8 +63,8 @@ public class GrpcConsumerSecurityTest extends CamelTestSupport {
@Before
public void startGrpcChannels() throws SSLException {
- String correctJwtToken = JwtHelper.createJwtToken(GRPC_JWT_CORRECT_SECRET, null, null);
- String incorrectJwtToken = JwtHelper.createJwtToken(GRPC_JWT_INCORRECT_SECRET, null, null);
+ String correctJwtToken = JwtHelper.createJwtToken(JwtAlgorithm.HMAC256, GRPC_JWT_CORRECT_SECRET, null, null);
+ String incorrectJwtToken = JwtHelper.createJwtToken(JwtAlgorithm.HMAC256, GRPC_JWT_INCORRECT_SECRET, null, null);
tlsChannel = NettyChannelBuilder.forAddress("localhost", GRPC_TLS_TEST_PORT)
.sslContext(GrpcSslContexts.forClient()
http://git-wip-us.apache.org/repos/asf/camel/blob/a558f54e/components/camel-grpc/src/test/java/org/apache/camel/component/grpc/GrpcProducerSecurityTest.java
----------------------------------------------------------------------
diff --git a/components/camel-grpc/src/test/java/org/apache/camel/component/grpc/GrpcProducerSecurityTest.java b/components/camel-grpc/src/test/java/org/apache/camel/component/grpc/GrpcProducerSecurityTest.java
index 2ba3016..3b2b753 100644
--- a/components/camel-grpc/src/test/java/org/apache/camel/component/grpc/GrpcProducerSecurityTest.java
+++ b/components/camel-grpc/src/test/java/org/apache/camel/component/grpc/GrpcProducerSecurityTest.java
@@ -27,7 +27,8 @@ import io.grpc.stub.StreamObserver;
import io.netty.handler.ssl.ClientAuth;
import io.netty.handler.ssl.SslProvider;
import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.component.grpc.server.auth.jwt.JwtServerInterceptor;
+import org.apache.camel.component.grpc.auth.jwt.JwtAlgorithm;
+import org.apache.camel.component.grpc.auth.jwt.JwtServerInterceptor;
import org.apache.camel.test.AvailablePortFinder;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.AfterClass;
@@ -66,7 +67,7 @@ public class GrpcProducerSecurityTest extends CamelTestSupport {
grpcServerWithJWT = NettyServerBuilder.forPort(GRPC_JWT_TEST_PORT)
.addService(new PingPongImpl())
- .intercept(new JwtServerInterceptor(GRPC_JWT_CORRECT_SECRET, null, null))
+ .intercept(new JwtServerInterceptor(JwtAlgorithm.HMAC256, GRPC_JWT_CORRECT_SECRET, null, null))
.build()
.start();