GERONIMO-6645 adding TokenAccessor to ensure testing a service layer is very doable without mocking a request
diff --git a/src/main/java/org/apache/geronimo/microprofile/impl/jwtauth/cdi/GeronimoJwtAuthExtension.java b/src/main/java/org/apache/geronimo/microprofile/impl/jwtauth/cdi/GeronimoJwtAuthExtension.java
index e1382a1..ed6d775 100644
--- a/src/main/java/org/apache/geronimo/microprofile/impl/jwtauth/cdi/GeronimoJwtAuthExtension.java
+++ b/src/main/java/org/apache/geronimo/microprofile/impl/jwtauth/cdi/GeronimoJwtAuthExtension.java
@@ -63,6 +63,7 @@
import org.apache.geronimo.microprofile.impl.jwtauth.config.GeronimoJwtAuthConfig;
import org.apache.geronimo.microprofile.impl.jwtauth.jwt.ContextualJsonWebToken;
+import org.apache.geronimo.microprofile.impl.jwtauth.servlet.TokenAccessor;
import org.apache.geronimo.microprofile.impl.jwtauth.servlet.JwtRequest;
import org.eclipse.microprofile.jwt.Claim;
import org.eclipse.microprofile.jwt.ClaimValue;
@@ -70,7 +71,7 @@
import org.eclipse.microprofile.jwt.JsonWebToken;
public class GeronimoJwtAuthExtension implements Extension {
- private final ThreadLocal<JwtRequest> request = new ThreadLocal<>();
+ private final ThreadLocal<TokenAccessor> request = new ThreadLocal<>();
private final Collection<Injection> injectionPoints = new HashSet<>(8);
private final Collection<Throwable> errors = new ArrayList<>();
@@ -106,7 +107,7 @@
.qualifiers(Default.Literal.INSTANCE, Any.Literal.INSTANCE)
.scope(ApplicationScoped.class)
.createWith(ctx -> new ContextualJsonWebToken(() -> {
- final JwtRequest request = this.request.get();
+ final TokenAccessor request = this.request.get();
if (request == null) {
throw new IllegalStateException("No JWT in this request");
}
@@ -143,7 +144,7 @@
return createInjection(claim, arg)
.map(it -> new Injection(claim.value(), claim.standard(), type) {
@Override
- Object createInstance(final JwtRequest jwtRequest) {
+ Object createInstance(final TokenAccessor jwtRequest) {
return ofNullable(it.createInstance(jwtRequest));
}
});
@@ -153,7 +154,7 @@
return createInjection(claim, arg)
.map(it -> new Injection(claim.value(), claim.standard(), type) {
@Override
- Object createInstance(final JwtRequest jwtRequest) {
+ Object createInstance(final TokenAccessor jwtRequest) {
return new ClaimValue<Object>() {
@Override
public String getName() {
@@ -178,7 +179,7 @@
if (JsonString.class.isAssignableFrom(clazz)) {
return of(new Injection(claim.value(), claim.standard(), clazz) {
@Override
- Object createInstance(final JwtRequest jwtRequest) {
+ Object createInstance(final TokenAccessor jwtRequest) {
final Object instance = super.createInstance(jwtRequest);
if (JsonString.class.isInstance(instance)) {
return instance;
@@ -190,7 +191,7 @@
if (JsonNumber.class.isAssignableFrom(clazz)) {
return of(new Injection(claim.value(), claim.standard(), clazz) {
@Override
- Object createInstance(final JwtRequest jwtRequest) {
+ Object createInstance(final TokenAccessor jwtRequest) {
final Object instance = super.createInstance(jwtRequest);
if (JsonNumber.class.isInstance(instance)) {
return instance;
@@ -205,7 +206,7 @@
if (JsonArray.class.isAssignableFrom(clazz)) {
return of(new Injection(claim.value(), claim.standard(), clazz) {
@Override
- Object createInstance(final JwtRequest jwtRequest) {
+ Object createInstance(final TokenAccessor jwtRequest) {
final Object instance = super.createInstance(jwtRequest);
if (instance == null) {
return null;
@@ -260,7 +261,7 @@
public void execute(final HttpServletRequest req, final ServletRunnable task) {
try {
- final JwtRequest jwtRequest = requireNonNull(JwtRequest.class.isInstance(req) ?
+ final TokenAccessor jwtRequest = requireNonNull(JwtRequest.class.isInstance(req) ?
JwtRequest.class.cast(req) : JwtRequest.class.cast(req.getAttribute(JwtRequest.class.getName())),
"No JwtRequest");
execute(jwtRequest, task);
@@ -269,7 +270,7 @@
}
}
- public void execute(final JwtRequest req, final ServletRunnable task) throws ServletException, IOException {
+ public void execute(final TokenAccessor req, final ServletRunnable task) throws ServletException, IOException {
request.set(req); // we want to track it ourself to support propagation properly when needed
try {
task.run();
@@ -348,7 +349,7 @@
return new ClaimLiteral(name, claims);
}
- Object createInstance(final JwtRequest jwtRequest) {
+ Object createInstance(final TokenAccessor jwtRequest) {
return transformer.apply(jwtRequest.getToken().getClaim(runtimeName));
}
diff --git a/src/main/java/org/apache/geronimo/microprofile/impl/jwtauth/jwt/JwtParser.java b/src/main/java/org/apache/geronimo/microprofile/impl/jwtauth/jwt/JwtParser.java
index e8ed870..66cd1c7 100644
--- a/src/main/java/org/apache/geronimo/microprofile/impl/jwtauth/jwt/JwtParser.java
+++ b/src/main/java/org/apache/geronimo/microprofile/impl/jwtauth/jwt/JwtParser.java
@@ -31,6 +31,7 @@
import javax.json.JsonString;
import org.apache.geronimo.microprofile.impl.jwtauth.JwtException;
+import org.apache.geronimo.microprofile.impl.jwtauth.cdi.GeronimoJwtAuthExtension;
import org.apache.geronimo.microprofile.impl.jwtauth.config.GeronimoJwtAuthConfig;
import org.eclipse.microprofile.jwt.Claims;
import org.eclipse.microprofile.jwt.JsonWebToken;
@@ -49,6 +50,9 @@
@Inject
private SignatureValidator signatureValidator;
+ @Inject
+ private GeronimoJwtAuthExtension extension;
+
private JsonReaderFactory readerFactory;
private String defaultKid;
@@ -91,6 +95,10 @@
}
signatureValidator.verifySignature(alg, kidMapper.loadKey(kid), jwt.substring(0, secondDot), jwt.substring(secondDot + 1));
+ return createToken(jwt, payload);
+ }
+
+ public GeronimoJsonWebToken createToken(final String jwt, final JsonObject payload) {
return new GeronimoJsonWebToken(jwt, payload);
}
diff --git a/src/main/java/org/apache/geronimo/microprofile/impl/jwtauth/servlet/GeronimoJwtAuthFilter.java b/src/main/java/org/apache/geronimo/microprofile/impl/jwtauth/servlet/GeronimoJwtAuthFilter.java
index 881f3bf..a8a995e 100644
--- a/src/main/java/org/apache/geronimo/microprofile/impl/jwtauth/servlet/GeronimoJwtAuthFilter.java
+++ b/src/main/java/org/apache/geronimo/microprofile/impl/jwtauth/servlet/GeronimoJwtAuthFilter.java
@@ -80,7 +80,7 @@
try {
final JwtRequest req = new JwtRequest(service, headerName, prefix, httpServletRequest);
- extension.execute(req, () -> chain.doFilter(req, response));
+ extension.execute(req.asTokenAccessor(), () -> chain.doFilter(req, response));
} catch (final Exception e) { // when not used with JAX-RS but directly Servlet
final HttpServletResponse httpServletResponse = HttpServletResponse.class.cast(response);
if (!httpServletResponse.isCommitted()) {
diff --git a/src/main/java/org/apache/geronimo/microprofile/impl/jwtauth/servlet/JwtRequest.java b/src/main/java/org/apache/geronimo/microprofile/impl/jwtauth/servlet/JwtRequest.java
index 25f7e02..15cb043 100644
--- a/src/main/java/org/apache/geronimo/microprofile/impl/jwtauth/servlet/JwtRequest.java
+++ b/src/main/java/org/apache/geronimo/microprofile/impl/jwtauth/servlet/JwtRequest.java
@@ -35,14 +35,12 @@
import org.apache.geronimo.microprofile.impl.jwtauth.jwt.JwtParser;
import org.eclipse.microprofile.jwt.JsonWebToken;
-public class JwtRequest extends HttpServletRequestWrapper {
- private final HttpServletRequest delegate;
+public class JwtRequest extends HttpServletRequestWrapper implements TokenAccessor {
private final Supplier<JsonWebToken> tokenExtractor;
private volatile JsonWebToken token; // cache for perf reasons
public JwtRequest(final JwtParser service, final String header, final String prefix, final HttpServletRequest request) {
super(request);
- this.delegate = request;
this.tokenExtractor = () -> {
if (token != null) {
@@ -54,7 +52,7 @@
return token;
}
- final String auth = delegate.getHeader(header);
+ final String auth = getHeader(header);
if (auth == null || auth.isEmpty()) {
throw new JwtException("No " + header + " header", HttpServletResponse.SC_UNAUTHORIZED);
}
@@ -81,6 +79,11 @@
});
}
+ public TokenAccessor asTokenAccessor() {
+ return this;
+ }
+
+ @Override
public JsonWebToken getToken() {
return tokenExtractor.get();
}
diff --git a/src/main/java/org/apache/geronimo/microprofile/impl/jwtauth/servlet/TokenAccessor.java b/src/main/java/org/apache/geronimo/microprofile/impl/jwtauth/servlet/TokenAccessor.java
new file mode 100644
index 0000000..83dec03
--- /dev/null
+++ b/src/main/java/org/apache/geronimo/microprofile/impl/jwtauth/servlet/TokenAccessor.java
@@ -0,0 +1,23 @@
+/*
+ * 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.geronimo.microprofile.impl.jwtauth.servlet;
+
+import org.eclipse.microprofile.jwt.JsonWebToken;
+
+public interface TokenAccessor {
+ JsonWebToken getToken();
+}