You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by jl...@apache.org on 2018/04/16 22:45:05 UTC
[01/38] tomee git commit: Testing code
Repository: tomee
Updated Branches:
refs/heads/master 3e487f0f9 -> 09ca434d9
Testing code
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/e55b4dcf
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/e55b4dcf
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/e55b4dcf
Branch: refs/heads/master
Commit: e55b4dcf3f6d1e657ff88749afa351d906a4376c
Parents: 715e7f2
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Tue Feb 20 09:29:35 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Tue Feb 20 09:29:35 2018 +0100
----------------------------------------------------------------------
container/openejb-core/pom.xml | 19 ++++
.../apache/openejb/core/security/JWTUtil.java | 100 +++++++++++++++++++
2 files changed, 119 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/e55b4dcf/container/openejb-core/pom.xml
----------------------------------------------------------------------
diff --git a/container/openejb-core/pom.xml b/container/openejb-core/pom.xml
index be1e710..c7feeee 100644
--- a/container/openejb-core/pom.xml
+++ b/container/openejb-core/pom.xml
@@ -712,6 +712,25 @@
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.eclipse.microprofile.config</groupId>
+ <artifactId>microprofile-config-api</artifactId>
+ <version>1.2</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.microprofile.jwt</groupId>
+ <artifactId>microprofile-jwt-auth-api</artifactId>
+ <version>1.1-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.nimbusds</groupId>
+ <artifactId>nimbus-jose-jwt</artifactId>
+ <version>5.1</version>
+ <scope>compile</scope>
+ </dependency>
+
</dependencies>
<profiles>
http://git-wip-us.apache.org/repos/asf/tomee/blob/e55b4dcf/container/openejb-core/src/test/java/org/apache/openejb/core/security/JWTUtil.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/test/java/org/apache/openejb/core/security/JWTUtil.java b/container/openejb-core/src/test/java/org/apache/openejb/core/security/JWTUtil.java
new file mode 100644
index 0000000..4ae438f
--- /dev/null
+++ b/container/openejb-core/src/test/java/org/apache/openejb/core/security/JWTUtil.java
@@ -0,0 +1,100 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.openejb.core.security;
+
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.JWSHeader;
+import com.nimbusds.jose.JWSSigner;
+import com.nimbusds.jose.crypto.MACSigner;
+import com.nimbusds.jose.crypto.RSASSASigner;
+import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.jwt.SignedJWT;
+
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.Key;
+import java.security.interfaces.RSAPrivateKey;
+import java.time.LocalDate;
+import java.util.Date;
+import java.util.UUID;
+
+import static java.time.ZoneId.systemDefault;
+
+public class JWTUtil {
+
+ protected static final String MYSHAREDSECRET = "abcdefghijklmnopqrstuvwxyzabcdef"; // at least 256 bits
+
+ private JWTUtil() {
+ // prevent direct instantiation
+ }
+
+ public static String createValidJwtAccessToken(String... scopes) throws Exception {
+ final SecretKey key = new SecretKeySpec(MYSHAREDSECRET.getBytes(), "hmac-sha256");
+
+ // Prepare JWT with claims set
+ final JWTClaimsSet.Builder claimsBuilder = createValidJwtClaimsSet();
+
+ if (scopes != null && scopes.length > 0) {
+ claimsBuilder.claim("scopes", scopes);
+ }
+
+ final JWTClaimsSet claimsSet = claimsBuilder.build();
+
+ final JWSHeader header = new JWSHeader(JWSAlgorithm.HS256);
+
+ return sign(claimsSet, header, key).serialize();
+ }
+
+ public static SignedJWT sign(final JWTClaimsSet jwtClaimsSet, final JWSHeader jwsHeader, final Key key) throws JOSEException {
+ JWSSigner signer = null;
+ if (RSAPrivateKey.class.isInstance(key)) {
+ signer = new RSASSASigner(RSAPrivateKey.class.cast(key));
+
+ } else if (SecretKey.class.isInstance(key)) {
+ signer = new MACSigner(SecretKey.class.cast(key).getEncoded());
+
+ } else {
+ throw new IllegalArgumentException(String.format("Class %s not supported", key.getClass().getName()));
+ }
+
+ SignedJWT signedJWT = new SignedJWT(
+ jwsHeader,
+ jwtClaimsSet);
+
+ signedJWT.sign(signer);
+
+ return signedJWT;
+ }
+
+ public static JWTClaimsSet.Builder createValidJwtClaimsSet() {
+ final LocalDate now = LocalDate.now();
+ return new JWTClaimsSet.Builder()
+ .expirationTime(new Date(new Date().getTime() + 1800000))
+ .issuer("https://apache.org")
+ .jwtID(UUID.randomUUID().toString())
+ .issueTime(toDate(now))
+ .expirationTime(toDate(now.plusDays(30)))
+ .notBeforeTime(toDate(now))
+ .claim("role", "ruler of the known universe")
+ .claim("token-type", "access-token");
+ }
+
+ public static Date toDate(final LocalDate localDate) {
+ return Date.from(localDate.atStartOfDay(systemDefault()).toInstant());
+ }
+}
\ No newline at end of file
[06/38] tomee git commit: Better handling of the internal application
Posted by jl...@apache.org.
Better handling of the internal application
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/7acf3146
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/7acf3146
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/7acf3146
Branch: refs/heads/master
Commit: 7acf3146b12e5bbd0e4db58ed432345ca4eec4ae
Parents: a2468e4
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Wed Feb 21 16:45:35 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Wed Feb 21 16:45:35 2018 +0100
----------------------------------------------------------------------
.../server/cxf/rs/MPJWTSecurityContextTest.java | 22 +++++++-------------
1 file changed, 8 insertions(+), 14 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/7acf3146/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
----------------------------------------------------------------------
diff --git a/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
index b7bceb5..266aa66 100644
--- a/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
+++ b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
@@ -23,6 +23,7 @@ import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.observer.Observes;
import org.apache.openejb.server.cxf.rs.event.ExtensionProviderRegistration;
import org.apache.openejb.server.cxf.rs.event.ServerCreated;
+import org.apache.openejb.server.rest.InternalApplication;
import org.apache.openejb.spi.SecurityService;
import org.apache.openejb.testing.Classes;
import org.apache.openejb.testing.Configuration;
@@ -101,7 +102,7 @@ public class MPJWTSecurityContextTest {
@LoginConfig(authMethod = "MP-JWT")
@ApplicationPath("/api")
- public class RestApplication extends Application {
+ public static class RestApplication extends Application {
}
@@ -122,22 +123,15 @@ public class MPJWTSecurityContextTest {
public void obs(@Observes final ServerCreated event) {
System.out.println("Observer.obs");
final ApplicationInfo appInfo = (ApplicationInfo) event.getServer().getEndpoint().get("javax.ws.rs.core.Application");
- final Application application = appInfo.getProvider();
- final LoginConfig annotation = application.getClass().getAnnotation(LoginConfig.class);
- if (annotation != null) {
- // add the ContainerRequestFilter on the fly
- }
- }
-
- public void extension(@Observes final ExtensionProviderRegistration registration) {
- System.out.println("Observer.extension");
- // nothing useful here because we cannot access the application
- final ApplicationInfo appInfo = (ApplicationInfo) registration.getServer().getEndpoint().get("javax.ws.rs.core.Application");
- final Application application = appInfo.getProvider();
+ final Application application = InternalApplication.class.isInstance(appInfo.getProvider())
+ ? InternalApplication.class.cast(appInfo.getProvider()).getOriginal()
+ : appInfo.getProvider();
final LoginConfig annotation = application.getClass().getAnnotation(LoginConfig.class);
if (annotation != null && "MP-JWT".equals(annotation.authMethod())) {
// add the ContainerRequestFilter on the fly
- registration.getProviders().add(new MySecuCtx());
+ if (InternalApplication.class.isInstance(appInfo.getProvider())) {
+ InternalApplication.class.cast(appInfo.getProvider()).getClasses().add(MySecuCtx.class);
+ }
}
}
}
[02/38] tomee git commit: small quick and dirty test
Posted by jl...@apache.org.
small quick and dirty test
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/d56dc9e9
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/d56dc9e9
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/d56dc9e9
Branch: refs/heads/master
Commit: d56dc9e98bc0db270413bbd553b1f13ef3a60b7c
Parents: e55b4dc
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Tue Feb 20 09:30:07 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Tue Feb 20 09:30:07 2018 +0100
----------------------------------------------------------------------
.../openejb/core/security/JwtSecurityTest.java | 363 +++++++++++++++++++
1 file changed, 363 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/d56dc9e9/container/openejb-core/src/test/java/org/apache/openejb/core/security/JwtSecurityTest.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/test/java/org/apache/openejb/core/security/JwtSecurityTest.java b/container/openejb-core/src/test/java/org/apache/openejb/core/security/JwtSecurityTest.java
new file mode 100644
index 0000000..8708074
--- /dev/null
+++ b/container/openejb-core/src/test/java/org/apache/openejb/core/security/JwtSecurityTest.java
@@ -0,0 +1,363 @@
+/**
+ * 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.openejb.core.security;
+
+import org.apache.openejb.OpenEJB;
+import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.assembler.classic.EjbJarInfo;
+import org.apache.openejb.assembler.classic.ProxyFactoryInfo;
+import org.apache.openejb.assembler.classic.SecurityServiceInfo;
+import org.apache.openejb.assembler.classic.StatelessSessionContainerInfo;
+import org.apache.openejb.assembler.classic.TransactionServiceInfo;
+import org.apache.openejb.config.ConfigurationFactory;
+import org.apache.openejb.core.LocalInitialContextFactory;
+import org.apache.openejb.core.security.jaas.GroupPrincipal;
+import org.apache.openejb.core.security.jaas.UserPrincipal;
+import org.apache.openejb.jee.EjbJar;
+import org.apache.openejb.jee.StatelessBean;
+import org.junit.AfterClass;
+import org.junit.Test;
+
+import javax.annotation.Resource;
+import javax.annotation.security.DeclareRoles;
+import javax.annotation.security.DenyAll;
+import javax.annotation.security.PermitAll;
+import javax.annotation.security.RolesAllowed;
+import javax.annotation.security.RunAs;
+import javax.ejb.SessionContext;
+import javax.ejb.Singleton;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+import java.security.Security;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.testng.AssertJUnit.assertFalse;
+
+public class JWTSecurityTest {
+
+ @AfterClass
+ public static void afterClass() throws Exception {
+ OpenEJB.destroy();
+ System.clearProperty(Context.INITIAL_CONTEXT_FACTORY);
+ Security.setProperty("login.configuration.provider", null);
+ }
+
+ private Assembler configureAssembler(final String defaultUser) throws Exception {
+ System.setProperty(Context.INITIAL_CONTEXT_FACTORY, LocalInitialContextFactory.class.getName());
+ Security.setProperty("login.configuration.provider", JaasConfig.class.getName());
+
+ final ConfigurationFactory config = new ConfigurationFactory();
+ final Assembler assembler = new Assembler();
+
+ assembler.createProxyFactory(config.configureService(ProxyFactoryInfo.class));
+ assembler.createTransactionManager(config.configureService(TransactionServiceInfo.class));
+
+ final SecurityServiceInfo serviceInfo = new SecurityServiceInfo();
+ serviceInfo.service = "SecurityService";
+ serviceInfo.className = SecurityServiceImpl.class.getName();
+ serviceInfo.id = "New Security Service";
+ serviceInfo.properties = new Properties();
+ if (defaultUser != null) {
+ // override the default user
+ serviceInfo.properties.setProperty("DefaultUser", defaultUser);
+
+ }
+
+ assembler.createSecurityService(serviceInfo);
+
+ // containers
+ assembler.createContainer(config.configureService(StatelessSessionContainerInfo.class));
+
+ final EjbJar ejbJar = new EjbJar("JwtTest");
+
+ ejbJar.addEnterpriseBean(new StatelessBean(FooBean.class));
+ ejbJar.addEnterpriseBean(new StatelessBean(BarBean.class));
+
+ final EjbJarInfo ejbJarInfo = config.configureApplication(ejbJar);
+
+ assembler.createApplication(ejbJarInfo);
+
+ return assembler;
+ }
+
+ @Test
+ public void test() throws Exception {
+ final Assembler assembler = configureAssembler(null);
+
+ final Properties props = new Properties();
+ props.setProperty("openejb.authentication.realmName", "jwt-realm");
+ props.setProperty(Context.SECURITY_PRINCIPAL, JWTUtil.createValidJwtAccessToken("committer", "community"));
+ props.setProperty(Context.SECURITY_CREDENTIALS, "");
+
+ final InitialContext ctx = new InitialContext(props);
+
+ final Project foo = (Project) ctx.lookup("FooBeanLocal");
+
+ foo.svnCheckout("");
+ foo.svnCommit("");
+
+ try {
+ foo.deleteProject("");
+ fail("Should not be allowed");
+ } catch (final Exception e) {
+ // good.
+ }
+
+ assertTrue("not in role committer", foo.isCallerInRole("committer"));
+ assertTrue("not in role community", foo.isCallerInRole("community"));
+ assertFalse("in role contributor", foo.isCallerInRole("contributor"));
+ assertTrue("Caller is not jonathan", foo.isCaller("jonathan"));
+
+ ctx.close();
+ assembler.destroy();
+ }
+
+ // When no credentials are provided, the default user/role should be "guest"
+ @Test
+ public void testUnauthenticatedUser() throws Exception {
+ final Assembler assembler = configureAssembler(null);
+
+ // no credentials provided, the default user should be "guest"
+ final Properties props = new Properties();
+
+ final InitialContext ctx = new InitialContext(props);
+
+ final Project foo = (Project) ctx.lookup("FooBeanLocal");
+
+ foo.svnCheckout("");
+ try {
+ foo.svnCommit("");
+ fail("Should not be allowed");
+ } catch (final Exception e) {
+ // good.
+ }
+
+ assertFalse("in role committer", foo.isCallerInRole("committer"));
+ assertFalse("in role community", foo.isCallerInRole("community"));
+ assertFalse("in role contributor", foo.isCallerInRole("contributor"));
+ assertTrue("not in role guest", foo.isCallerInRole("guest"));
+ assertTrue("Caller is not guest", foo.isCaller("guest"));
+
+ ctx.close();
+ assembler.destroy();
+ }
+
+ // Just to be sure we can override the default user (ie. guest)
+ @Test
+ public void testDefaultUser() throws Exception {
+ final Assembler assembler = configureAssembler("public");
+
+ // no credentials provided, the default user should be "guest"
+ final Properties props = new Properties();
+
+ final InitialContext ctx = new InitialContext(props);
+
+ final Project foo = (Project) ctx.lookup("FooBeanLocal");
+
+ foo.svnCheckout("");
+ try {
+ foo.svnCommit("");
+ fail("Should not be allowed");
+ } catch (final Exception e) {
+ // good.
+ }
+
+ assertFalse("in role committer", foo.isCallerInRole("committer"));
+ assertFalse("in role community", foo.isCallerInRole("community"));
+ assertFalse("in role contributor", foo.isCallerInRole("contributor"));
+ assertFalse("in role guest", foo.isCallerInRole("guest"));
+ assertTrue("Caller is not public", foo.isCaller("public"));
+
+ ctx.close();
+ assembler.destroy();
+ }
+
+ @Singleton
+ @DeclareRoles({"committer", "contributor", "community", "guest", "public"})
+ public static class FooBean implements Project {
+
+ @Resource
+ private SessionContext context;
+
+ @Override
+ @RolesAllowed({"committer"})
+ public String svnCommit(final String s) {
+ return s;
+ }
+
+ @Override
+ @RolesAllowed({"committer", "contributor"})
+ public String submitPatch(final String s) {
+ return s;
+ }
+
+ @Override
+ @PermitAll
+ public String svnCheckout(final String s) {
+ return s;
+ }
+
+ @Override
+ @DenyAll
+ public String deleteProject(final String s) {
+ return s;
+ }
+
+ @Override
+ public boolean isCallerInRole(final String role) {
+ return context.isCallerInRole(role);
+ }
+
+ @Override
+ public boolean isCaller(final String user) {
+ return context.getCallerPrincipal().getName().equals(user);
+ }
+ }
+
+ @Singleton
+ @RunAs("contributor")
+ @DeclareRoles({"committer", "contributor", "community"})
+ public static class BarBean implements Project {
+
+ @Resource
+ private SessionContext context;
+
+ @Override
+ @RolesAllowed({"committer"})
+ public String svnCommit(final String s) {
+ return s;
+ }
+
+ @Override
+ @RolesAllowed({"committer", "contributor"})
+ public String submitPatch(final String s) {
+ return s;
+ }
+
+ @Override
+ @PermitAll
+ public String svnCheckout(final String s) {
+ return s;
+ }
+
+ @Override
+ @DenyAll
+ public String deleteProject(final String s) {
+ return s;
+ }
+
+ @Override
+ @PermitAll
+ public boolean isCallerInRole(final String role) {
+ return context.isCallerInRole(role);
+ }
+
+ @Override
+ @PermitAll
+ public boolean isCaller(final String user) {
+ return context.getCallerPrincipal().getName().equals(user);
+ }
+ }
+
+ public interface Project {
+
+ String svnCommit(String s);
+
+ String submitPatch(String s);
+
+ String svnCheckout(String s);
+
+ String deleteProject(String s);
+
+ boolean isCaller(String s);
+
+ boolean isCallerInRole(String s);
+ }
+
+ public static class JaasConfig extends Configuration {
+
+ @Override
+ public AppConfigurationEntry[] getAppConfigurationEntry(final String name) {
+ final Set<AppConfigurationEntry> entries = new HashSet<AppConfigurationEntry>();
+
+ final Map<String, Object> options = new HashMap<String, Object>();
+
+ entries.add(new AppConfigurationEntry(
+ JWTLoginModule.class.getName(),
+ AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
+ options
+ ));
+ return entries.toArray(new AppConfigurationEntry[entries.size()]);
+ }
+ }
+
+ public static class JWTLoginModule implements LoginModule {
+
+ private Subject subject;
+ private CallbackHandler callbackHandler;
+ private Map<String, ?> sharedState;
+ private Map<String, ?> options;
+
+ @Override
+ public void initialize(final Subject subject, final CallbackHandler callbackHandler, final Map<String, ?> sharedState, final Map<String, ?> options) {
+ this.subject = subject;
+ this.callbackHandler = callbackHandler;
+ this.sharedState = sharedState;
+ this.options = options;
+ System.out.println("JWTLoginModule.initialize");
+ }
+
+ @Override
+ public boolean login() throws LoginException {
+ System.out.println("JWTLoginModule.login");
+ subject.getPrincipals().add(new UserPrincipal("jonathan"));
+ subject.getPrincipals().add(new GroupPrincipal("committer"));
+ subject.getPrincipals().add(new GroupPrincipal("community"));
+ return true;
+ }
+
+ @Override
+ public boolean commit() throws LoginException {
+ System.out.println("JWTLoginModule.commit");
+ return true;
+ }
+
+ @Override
+ public boolean abort() throws LoginException {
+ System.out.println("JWTLoginModule.abort");
+ return true;
+ }
+
+ @Override
+ public boolean logout() throws LoginException {
+ System.out.println("JWTLoginModule.logout");
+ return true;
+ }
+ }
+}
[15/38] tomee git commit: See if we can run something
Posted by jl...@apache.org.
See if we can run something
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/9c691901
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/9c691901
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/9c691901
Branch: refs/heads/master
Commit: 9c691901d10df7482ce60529443add1c8b9eda8f
Parents: 7639e0d
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Fri Feb 23 14:35:51 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Fri Feb 23 14:35:51 2018 +0100
----------------------------------------------------------------------
tck/mp-jwt-embedded/pom.xml | 5 +++
.../src/test/resources/arquillian.xml | 37 ++++++++++++++++++++
tck/mp-jwt-embedded/src/test/resources/dev.xml | 5 ++-
3 files changed, 46 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/9c691901/tck/mp-jwt-embedded/pom.xml
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/pom.xml b/tck/mp-jwt-embedded/pom.xml
index fac5766..ddbccec 100644
--- a/tck/mp-jwt-embedded/pom.xml
+++ b/tck/mp-jwt-embedded/pom.xml
@@ -85,6 +85,11 @@
<artifactId>arquillian-container-test-spi</artifactId>
<version>${version.arquillian}</version>
</dependency>
+ <dependency>
+ <groupId>org.jboss.arquillian.testng</groupId>
+ <artifactId>arquillian-testng-container</artifactId>
+ <version>${version.arquillian}</version>
+ </dependency>
<dependency>
<groupId>org.bitbucket.b_c</groupId>
http://git-wip-us.apache.org/repos/asf/tomee/blob/9c691901/tck/mp-jwt-embedded/src/test/resources/arquillian.xml
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/test/resources/arquillian.xml b/tck/mp-jwt-embedded/src/test/resources/arquillian.xml
new file mode 100644
index 0000000..caab73b
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/test/resources/arquillian.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+
+ 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.
+-->
+<arquillian
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://jboss.org/schema/arquillian
+ http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
+
+ <container qualifier="tomee-embedded" default="true">
+ <configuration>
+ <property name="catalina_opts">-Xmx512m -XX:MaxPermSize=512m</property>
+ <property name="httpPort">-1</property>
+ <property name="stopPort">-1</property>
+ <property name="ajpPort">-1</property>
+ <property name="dir">target/tomee-tck</property>
+ <property name="appWorkingDir">target/tck-workdir</property>
+ <property name="simpleLog">true</property>
+ <property name="properties"></property>
+ </configuration>
+ </container>
+</arquillian>
http://git-wip-us.apache.org/repos/asf/tomee/blob/9c691901/tck/mp-jwt-embedded/src/test/resources/dev.xml
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/test/resources/dev.xml b/tck/mp-jwt-embedded/src/test/resources/dev.xml
index c2b24b8..16038c9 100644
--- a/tck/mp-jwt-embedded/src/test/resources/dev.xml
+++ b/tck/mp-jwt-embedded/src/test/resources/dev.xml
@@ -42,6 +42,7 @@
</groups>
<classes>
<class name="org.eclipse.microprofile.jwt.tck.parsing.TokenValidationTest" />
+ <!--
<class name="org.eclipse.microprofile.jwt.tck.util.TokenUtilsTest" />
<class name="org.eclipse.microprofile.jwt.tck.parsing.TestTokenClaimTypesTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.UnsecuredPingTest" />
@@ -51,8 +52,10 @@
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.ProviderInjectionTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.RolesAllowedTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.InvalidTokenTest" />
+ -->
</classes>
</test>
+ <!--
<test name="extended-tests" verbose="10">
<groups>
<define name="extended-groups">
@@ -75,6 +78,6 @@
<class name="org.eclipse.microprofile.jwt.tck.container.jacc.SubjectTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.servlet.ServletTest" />
</classes>
-
</test>
+ -->
</suite>
[22/38] tomee git commit: Different CDI approach
Posted by jl...@apache.org.
Different CDI approach
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/d81bd39d
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/d81bd39d
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/d81bd39d
Branch: refs/heads/master
Commit: d81bd39d0df71608bc2ae9f334df344e04b5081f
Parents: 2b9950f
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Fri Mar 2 08:52:59 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Fri Mar 2 08:52:59 2018 +0100
----------------------------------------------------------------------
.../tomee/microprofile/jwt/cdi/ClaimBean.java | 187 ++++++++++
.../jwt/cdi/ClaimInjectionPoint.java | 69 ++++
.../jwt/cdi/ClaimProviderBeanAttributes.java | 66 ----
.../jwt/cdi/ClaimValueProducer.java | 80 -----
.../microprofile/jwt/cdi/DefaultLiteral.java | 24 ++
.../microprofile/jwt/cdi/JsonValueProducer.java | 109 ------
.../microprofile/jwt/cdi/JsonbProducer.java | 2 +-
.../microprofile/jwt/cdi/MPJWTCDIExtension.java | 347 +++----------------
.../microprofile/jwt/cdi/MPJWTProducer.java | 4 +
.../jwt/cdi/RawClaimTypeProducer.java | 80 -----
tck/mp-jwt-embedded/src/test/resources/dev.xml | 12 +-
11 files changed, 329 insertions(+), 651 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/d81bd39d/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
new file mode 100644
index 0000000..d04d807
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
@@ -0,0 +1,187 @@
+/*
+ * 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.tomee.microprofile.jwt.cdi;
+
+import org.eclipse.microprofile.jwt.Claim;
+import org.eclipse.microprofile.jwt.Claims;
+
+import javax.enterprise.context.Dependent;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Annotated;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.PassivationCapable;
+import javax.inject.Provider;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+public class ClaimBean<T> implements Bean<T>, PassivationCapable {
+
+ private final static Set<Annotation> QUALIFIERS = new HashSet<>();
+
+ private final BeanManager bm;
+ private final Class rawType;
+ private final Set<Type> types;
+ private final String id;
+
+ public ClaimBean(final BeanManager bm, final Type type) {
+ this.bm = bm;
+ types = new HashSet<>();
+ types.add(type);
+ rawType = getRawType(type);
+ this.id = "ClaimBean_" + types;
+ }
+
+ private Class getRawType(Type type) {
+ if (type instanceof Class) {
+ return (Class) type;
+
+ } else if (type instanceof ParameterizedType) {
+ final ParameterizedType paramType = (ParameterizedType) type;
+
+ return (Class) paramType.getRawType();
+ }
+
+ // todo deal with Optional here?
+
+ throw new UnsupportedOperationException("Unsupported type " + type);
+ }
+
+
+ @Override
+ public Set<InjectionPoint> getInjectionPoints() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Class<?> getBeanClass() {
+ return rawType;
+ }
+
+ @Override
+ public boolean isNullable() {
+ return false;
+ }
+
+ @Override
+ public void destroy(T instance, CreationalContext<T> context) {
+
+ }
+
+ @Override
+ public Set<Type> getTypes() {
+ return types;
+ }
+
+ @Override
+ public Set<Annotation> getQualifiers() {
+ return QUALIFIERS;
+ }
+
+ @Override
+ public Class<? extends Annotation> getScope() {
+ return Dependent.class;
+ }
+
+ @Override
+ public String getName() {
+ return null;
+ }
+
+ @Override
+ public Set<Class<? extends Annotation>> getStereotypes() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public boolean isAlternative() {
+ return false;
+ }
+
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public T create(final CreationalContext<T> context) {
+ final InjectionPoint ip = (InjectionPoint) bm.getInjectableReference(new ClaimInjectionPoint(this), context);
+ if (ip == null) {
+ throw new IllegalStateException("Could not retrieve InjectionPoint");
+ }
+
+ final Annotated annotated = ip.getAnnotated();
+ Claim claim = annotated.getAnnotation(Claim.class);
+ final String key = getClaimKey(claim);
+
+ if (annotated.getBaseType() instanceof ParameterizedType) {
+ final ParameterizedType paramType = (ParameterizedType) annotated.getBaseType();
+ final Type rawType = paramType.getRawType();
+ if (rawType instanceof Class && paramType.getActualTypeArguments().length == 1) {
+
+ final Class<?> rawTypeClass = ((Class<?>) rawType);
+
+ // handle Provider<T>
+ if (rawTypeClass.isAssignableFrom(Provider.class)) {
+ final Class clazz = (Class) paramType.getActualTypeArguments()[0]; //X TODO check type again, etc
+ return (T) getClaimValue(key, clazz);
+ }
+
+ // handle Optional<T>
+ if (rawTypeClass.isAssignableFrom(Optional.class)) {
+ final Class clazz = (Class) paramType.getActualTypeArguments()[0]; //X TODO check type again, etc
+ return (T) getClaimValue(key, clazz);
+ }
+
+ // handle Set<T>
+ if (rawTypeClass.isAssignableFrom(Set.class)) {
+ Class clazz = (Class) paramType.getActualTypeArguments()[0]; //X TODO check type again, etc
+ return getClaimValue(key, clazz);
+ }
+
+ // handle List<T>
+ if (rawTypeClass.isAssignableFrom(List.class)) {
+ final Class clazz = (Class) paramType.getActualTypeArguments()[0]; //X TODO check type again, etc
+ return getClaimValue(key, clazz);
+ }
+ }
+
+ } else {
+ // handle Raw types
+ final Class clazz = (Class) annotated.getBaseType();
+ return getClaimValue(key, clazz);
+ }
+
+ throw new IllegalStateException("Unhandled ClaimValue type");
+ }
+
+ public static String getClaimKey(final Claim claim) {
+ return claim.standard() == Claims.UNKNOWN ? claim.value() : claim.standard().name();
+ }
+
+ private T getClaimValue(final String key, final Class clazz) {
+ return null; // todo
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/tomee/blob/d81bd39d/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimInjectionPoint.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimInjectionPoint.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimInjectionPoint.java
new file mode 100644
index 0000000..a281014
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimInjectionPoint.java
@@ -0,0 +1,69 @@
+/*
+ * 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.tomee.microprofile.jwt.cdi;
+
+import javax.enterprise.inject.spi.Annotated;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.InjectionPoint;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Member;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.Set;
+
+class ClaimInjectionPoint implements InjectionPoint{
+ private final Bean bean;
+
+ ClaimInjectionPoint(Bean bean) {
+ this.bean = bean;
+ }
+
+ @Override
+ public boolean isTransient() {
+ return false;
+ }
+
+ @Override
+ public boolean isDelegate() {
+ return false;
+ }
+
+ @Override
+ public Type getType() {
+ return InjectionPoint.class;
+ }
+
+ @Override
+ public Set<Annotation> getQualifiers() {
+ return Collections.singleton(DefaultLiteral.INSTANCE);
+ }
+
+ @Override
+ public Member getMember() {
+ return null;
+ }
+
+ @Override
+ public Bean<?> getBean() {
+ return bean;
+ }
+
+ @Override
+ public Annotated getAnnotated() {
+ return null;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/d81bd39d/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimProviderBeanAttributes.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimProviderBeanAttributes.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimProviderBeanAttributes.java
deleted file mode 100644
index f15a3fe..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimProviderBeanAttributes.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.tomee.microprofile.jwt.cdi;
-
-import javax.enterprise.inject.spi.BeanAttributes;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import java.util.Set;
-
-public class ClaimProviderBeanAttributes implements BeanAttributes<Object> {
-
- private final BeanAttributes<Object> delegate;
- private final Set<Type> types;
- private final Set<Annotation> qualifiers;
-
- public ClaimProviderBeanAttributes(final BeanAttributes<Object> delegate, final Set<Type> types, final Set<Annotation> qualifiers) {
- this.delegate = delegate;
- this.types = types;
- this.qualifiers = qualifiers;
- }
-
- @Override
- public Set<Type> getTypes() {
- return types;
- }
-
- @Override
- public Set<Annotation> getQualifiers() {
- return qualifiers;
- }
-
- @Override
- public Class<? extends Annotation> getScope() {
- return delegate.getScope();
- }
-
- @Override
- public String getName() {
- return delegate.getName();
- }
-
- @Override
- public Set<Class<? extends Annotation>> getStereotypes() {
- return delegate.getStereotypes();
- }
-
- @Override
- public boolean isAlternative() {
- return delegate.isAlternative();
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/d81bd39d/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java
deleted file mode 100644
index b0e2e7b..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java
+++ /dev/null
@@ -1,80 +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.tomee.microprofile.jwt.cdi;
-
-import org.eclipse.microprofile.jwt.Claim;
-import org.eclipse.microprofile.jwt.ClaimValue;
-import org.eclipse.microprofile.jwt.Claims;
-
-import javax.enterprise.inject.Produces;
-import javax.enterprise.inject.spi.InjectionPoint;
-import javax.inject.Inject;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.Optional;
-
-public class ClaimValueProducer<T> {
-
- @Inject
- private MPJWTProducer producer;
-
- @Produces
- @Claim("")
- ClaimValue<T> produce(final InjectionPoint ip) {
- String name = getName(ip);
- ClaimValue<Optional<T>> cv = producer.generalClaimValueProducer(name);
- ClaimValue<T> returnValue = (ClaimValue<T>) cv;
- Optional<T> value = cv.getValue();
-
- // Pull out the ClaimValue<T> T type,
- Type matchType = ip.getType();
- Type actualType = Object.class;
- boolean isOptional = false;
- if (matchType instanceof ParameterizedType) {
- actualType = ((ParameterizedType) matchType).getActualTypeArguments()[0];
-
- if (actualType instanceof ParameterizedType) {
- isOptional = ParameterizedType.class.cast(actualType).getRawType().getTypeName()
- .startsWith(Optional.class.getTypeName());
- }
-
- if (isOptional) {
- actualType = ((ParameterizedType) actualType).getActualTypeArguments()[0];
- }
- }
-
- if (!actualType.getTypeName().startsWith(Optional.class.getTypeName())) {
- T nestedValue = value.orElse(null);
- ClaimValueWrapper<T> wrapper = new ClaimValueWrapper<>(cv.getName());
- wrapper.setValue(nestedValue);
- returnValue = wrapper;
- }
- return returnValue;
- }
-
- private String getName(final InjectionPoint ip) {
- String name = null;
- for (Annotation ann : ip.getQualifiers()) {
- if (ann instanceof Claim) {
- Claim claim = (Claim) ann;
- name = claim.standard() == Claims.UNKNOWN ? claim.value() : claim.standard().name();
- }
- }
- return name;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/d81bd39d/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/DefaultLiteral.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/DefaultLiteral.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/DefaultLiteral.java
new file mode 100644
index 0000000..d741258
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/DefaultLiteral.java
@@ -0,0 +1,24 @@
+/*
+ * 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.tomee.microprofile.jwt.cdi;
+
+import javax.enterprise.inject.Default;
+import javax.enterprise.util.AnnotationLiteral;
+
+class DefaultLiteral extends AnnotationLiteral<Default> implements Default {
+ public static Default INSTANCE = new DefaultLiteral();
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/d81bd39d/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonValueProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonValueProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonValueProducer.java
deleted file mode 100644
index 645b41b..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonValueProducer.java
+++ /dev/null
@@ -1,109 +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.tomee.microprofile.jwt.cdi;
-
-import org.eclipse.microprofile.jwt.Claim;
-import org.eclipse.microprofile.jwt.Claims;
-
-import javax.enterprise.inject.Produces;
-import javax.enterprise.inject.spi.InjectionPoint;
-import javax.inject.Inject;
-import javax.json.JsonArray;
-import javax.json.JsonNumber;
-import javax.json.JsonObject;
-import javax.json.JsonString;
-import javax.json.JsonValue;
-import java.lang.annotation.Annotation;
-import java.util.Optional;
-import java.util.Set;
-
-public class JsonValueProducer {
-
- @Inject
- private MPJWTProducer producer;
-
- @Produces
- @Claim("")
- public JsonString getJsonString(final InjectionPoint ip) {
- return getValue(ip);
- }
-
- @Produces
- @Claim("")
- public Optional<JsonString> getOptionalJsonString(final InjectionPoint ip) {
- return getOptionalValue(ip);
- }
-
- @Produces
- @Claim("")
- public JsonNumber getJsonNumber(final InjectionPoint ip) {
- return getValue(ip);
- }
-
- @Produces
- @Claim("")
- public Optional<JsonNumber> getOptionalJsonNumber(final InjectionPoint ip) {
- return getOptionalValue(ip);
- }
-
- @Produces
- @Claim("")
- public JsonArray getJsonArray(final InjectionPoint ip) {
- return getValue(ip);
- }
-
- @Produces
- @Claim("")
- public Optional<JsonArray> getOptionalJsonArray(final InjectionPoint ip) {
- return getOptionalValue(ip);
- }
-
- @Produces
- @Claim("")
- public JsonObject getJsonObject(final InjectionPoint ip) {
- return getValue(ip);
- }
-
- @Produces
- @Claim("")
- public Optional<JsonObject> getOptionalJsonObject(final InjectionPoint ip) {
- return getOptionalValue(ip);
- }
-
- public <T extends JsonValue> T getValue(final InjectionPoint ip) {
- String name = getName(ip);
- T jsonValue = (T) producer.generalJsonValueProducer(name);
- return jsonValue;
- }
-
- public <T extends JsonValue> Optional<T> getOptionalValue(final InjectionPoint ip) {
- String name = getName(ip);
- T jsonValue = (T) producer.generalJsonValueProducer(name);
- return Optional.ofNullable(jsonValue);
- }
-
- String getName(final InjectionPoint ip) {
- String name = null;
- for (Annotation ann : ip.getQualifiers()) {
- if (ann instanceof Claim) {
- Claim claim = (Claim) ann;
- name = claim.standard() == Claims.UNKNOWN ? claim.value() : claim.standard().name();
- }
- }
- return name;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/d81bd39d/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java
index 7774cbf..297dfb3 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java
@@ -30,7 +30,7 @@ public class JsonbProducer {
private static Logger log = Logger.getLogger(MPJWTCDIExtension.class.getName());
@Produces
- public Jsonb jsonb() {
+ public Jsonb create() {
return JsonbBuilder.create();
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/d81bd39d/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
index 7375d65..88981d4 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
@@ -21,348 +21,79 @@ import org.apache.tomee.microprofile.jwt.MPJWTInitializer;
import org.apache.tomee.microprofile.jwt.TCKTokenParser;
import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfoProvider;
import org.eclipse.microprofile.jwt.Claim;
-import org.eclipse.microprofile.jwt.Claims;
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.context.SessionScoped;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.AfterBeanDiscovery;
import javax.enterprise.inject.spi.AfterDeploymentValidation;
-import javax.enterprise.inject.spi.BeanAttributes;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.BeforeBeanDiscovery;
-import javax.enterprise.inject.spi.DeploymentException;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.InjectionPoint;
-import javax.enterprise.inject.spi.ProcessBeanAttributes;
import javax.enterprise.inject.spi.ProcessInjectionPoint;
-import javax.enterprise.inject.spi.ProcessProducer;
import javax.inject.Provider;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Optional;
+import java.util.Map;
import java.util.Set;
+import java.util.function.Predicate;
import java.util.logging.Logger;
+import java.util.stream.Collectors;
public class MPJWTCDIExtension implements Extension {
- private static Logger log = Logger.getLogger(MPJWTCDIExtension.class.getName());
- /**
- * A map of claim,type pairs to the injection site information
- */
- private HashMap<ClaimIPType, ClaimIP> claims = new HashMap<>();
- private Set<Type> providerOptionalTypes = new HashSet<>();
- private Set<Type> providerTypes = new HashSet<>();
- private Set<Type> rawTypes = new HashSet<>();
- private Set<Annotation> rawTypeQualifiers = new HashSet<>();
- private Set<Annotation> providerQualifiers = new HashSet<>();
- /**
- * Register the MPJWTProducer JsonWebToken producer bean
- *
- * @param bbd before discovery event
- * @param beanManager cdi bean manager
- */
- public void observeBeforeBeanDiscovery(@Observes BeforeBeanDiscovery bbd, BeanManager beanManager) {
- log.fine("MPJWTExtension(), added JWTPrincipalProducer");
- bbd.addAnnotatedType(beanManager.createAnnotatedType(TCKTokenParser.class));
- bbd.addAnnotatedType(beanManager.createAnnotatedType(JsonbProducer.class));
- bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTFilter.class));
- bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTInitializer.class));
- bbd.addAnnotatedType(beanManager.createAnnotatedType(JWTAuthContextInfoProvider.class));
- bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTProducer.class));
- bbd.addAnnotatedType(beanManager.createAnnotatedType(RawClaimTypeProducer.class));
- bbd.addAnnotatedType(beanManager.createAnnotatedType(ClaimValueProducer.class));
- bbd.addAnnotatedType(beanManager.createAnnotatedType(JsonValueProducer.class));
- }
+ private static Logger logger = Logger.getLogger(MPJWTCDIExtension.class.getName());
- /**
- * Replace the general producer method BeanAttributes with one bound to the collected injection site
- * types to properly reflect all of the type locations the producer method applies to.
- *
- * @param pba the ProcessBeanAttributes
- * @see ClaimProviderBeanAttributes
- */
- public void addTypeToClaimProducer(@Observes ProcessBeanAttributes pba) {
- if (pba.getAnnotated().isAnnotationPresent(Claim.class)) {
- Claim claim = pba.getAnnotated().getAnnotation(Claim.class);
- if (claim.value().length() == 0 && claim.standard() == Claims.UNKNOWN) {
- log.fine(String.format("addTypeToClaimProducer: %s\n", pba.getAnnotated()));
- BeanAttributes delegate = pba.getBeanAttributes();
- String name = delegate.getName();
- if (delegate.getTypes().contains(Optional.class)) {
- if (providerOptionalTypes.size() == 0) {
- providerOptionalTypes.add(Optional.class);
- }
- pba.setBeanAttributes(new ClaimProviderBeanAttributes(delegate, providerOptionalTypes, providerQualifiers));
- // This is
- } else if (name != null && name.startsWith("RawClaimTypeProducer#")) {
- if (rawTypes.size() == 0) {
- rawTypes.add(Object.class);
- }
- pba.setBeanAttributes(new ClaimProviderBeanAttributes(delegate, rawTypes, rawTypeQualifiers));
- log.fine(String.format("Setup RawClaimTypeProducer BeanAttributes"));
- }
- }
- }
- }
+ private static final Predicate<InjectionPoint> NOT_PROVIDERS = ip -> (ip.getType() instanceof Class) || (ip.getType() instanceof ParameterizedType && ((ParameterizedType)ip.getType()).getRawType() != Provider.class);
+ private static final Map<Type, Type> REPLACED_TYPES = new HashMap<>();
- public void afterDeploymentValidation(@Observes AfterDeploymentValidation event, BeanManager beanManager) {
+ static {
+ REPLACED_TYPES.put(double.class, Double.class);
+ REPLACED_TYPES.put(int.class, Integer.class);
+ REPLACED_TYPES.put(float.class, Float.class);
+ REPLACED_TYPES.put(long.class, Long.class);
+ REPLACED_TYPES.put(boolean.class, Boolean.class);
}
- void doProcessProducers(@Observes ProcessProducer pp) {
- }
+ private Set<InjectionPoint> injectionPoints = new HashSet<>();
- /**
- * Handle the non-{@linkplain Provider}, {@linkplain org.eclipse.microprofile.jwt.ClaimValue}, and
- * {@linkplain javax.json.JsonValue} claim injection types.
- *
- * @param pip - the injection point event information
- * @see RawClaimTypeProducer
- */
- void processClaimInjections(@Observes ProcessInjectionPoint pip) {
- log.fine(String.format("pipRaw: %s", pip.getInjectionPoint()));
- InjectionPoint ip = pip.getInjectionPoint();
- if (ip.getAnnotated().isAnnotationPresent(Claim.class)) {
- Claim claim = ip.getAnnotated().getAnnotation(Claim.class);
- if (ip.getType() instanceof Class) {
- Class rawClass = (Class) ip.getType();
- // Primative types
- if (Modifier.isFinal(rawClass.getModifiers())) {
- rawTypes.add(ip.getType());
- rawTypeQualifiers.add(claim);
- log.fine(String.format("+++ Added Claim raw type: %s", ip.getType()));
- Class declaringClass = ip.getMember().getDeclaringClass();
- Annotation[] appScoped = declaringClass.getAnnotationsByType(ApplicationScoped.class);
- Annotation[] sessionScoped = declaringClass.getAnnotationsByType(SessionScoped.class);
- if ((appScoped != null && appScoped.length > 0) || (sessionScoped != null && sessionScoped.length > 0)) {
- String err = String.format("A raw type cannot be injected into application/session scope: IP=%s", ip);
- pip.addDefinitionError(new DeploymentException(err));
- }
- }
- // This handles collections of primative types
- } else if (isRawParameterizedType(ip.getType())) {
- log.fine(String.format("+++ Added Claim ParameterizedType: %s", ip.getType()));
- rawTypes.add(ip.getType());
- rawTypeQualifiers.add(claim);
- }
- } else {
- log.fine(String.format("Skipping pip: %s, type: %s/%s", ip, ip.getType(), ip.getType().getClass()));
+ public void collectConfigProducer(@Observes final ProcessInjectionPoint<?, ?> pip) {
+ final Claim claim = pip.getInjectionPoint().getAnnotated().getAnnotation(Claim.class);
+ if (claim != null) {
+ injectionPoints.add(pip.getInjectionPoint());
}
}
- /**
- * Collect the types of all {@linkplain Provider} injection points annotated with {@linkplain Claim}.
- *
- * @param pip - the injection point event information
- */
- void processClaimProviderInjections(@Observes ProcessInjectionPoint<?, ? extends Provider> pip) {
- log.fine(String.format("pip: %s", pip.getInjectionPoint()));
- final InjectionPoint ip = pip.getInjectionPoint();
- if (ip.getAnnotated().isAnnotationPresent(Claim.class)) {
- Claim claim = ip.getAnnotated().getAnnotation(Claim.class);
- if (claim.value().length() == 0 && claim.standard() == Claims.UNKNOWN) {
- pip.addDefinitionError(new DeploymentException("@Claim at: " + ip + " has no name or valid standard enum setting"));
- }
- boolean usesEnum = claim.standard() != Claims.UNKNOWN;
- final String claimName = usesEnum ? claim.standard().name() : claim.value();
- log.fine(String.format("Checking Provider Claim(%s), ip: %s", claimName, ip));
- ClaimIP claimIP = claims.get(claimName);
- Type matchType = ip.getType();
- // The T from the Provider<T> injection site
- Type actualType = ((ParameterizedType) matchType).getActualTypeArguments()[0];
- // Don't add Optional or JsonValue as this is handled specially
- if (!optionalOrJsonValue(actualType)) {
- rawTypes.add(actualType);
- } else if (!actualType.getTypeName().startsWith("javax.json.Json")) {
- // Validate that this is not an Optional<JsonValue>
- Type innerType = ((ParameterizedType) actualType).getActualTypeArguments()[0];
- if (!innerType.getTypeName().startsWith("javax.json.Json")) {
- providerOptionalTypes.add(actualType);
- providerQualifiers.add(claim);
- }
- }
- rawTypeQualifiers.add(claim);
- ClaimIPType key = new ClaimIPType(claimName, actualType);
- if (claimIP == null) {
- claimIP = new ClaimIP(actualType, actualType, false, claim);
- claimIP.setProviderSite(true);
- claims.put(key, claimIP);
- }
- claimIP.getInjectionPoints().add(ip);
- log.fine(String.format("+++ Added Provider Claim(%s) ip: %s", claimName, ip));
+ public void registerConfigProducer(@Observes final AfterBeanDiscovery abd, final BeanManager bm) {
+ final Set<Type> types = injectionPoints.stream()
+ .filter(NOT_PROVIDERS)
+ .map(ip -> REPLACED_TYPES.getOrDefault(ip.getType(), ip.getType()))
+ .collect(Collectors.toSet());
- }
- }
-
- /**
- * Create producer methods for each ClaimValue injection site
- *
- * @param event - AfterBeanDiscovery
- * @param beanManager - CDI bean manager
- */
- void observesAfterBeanDiscovery(@Observes final AfterBeanDiscovery event, final BeanManager beanManager) {
- log.fine(String.format("observesAfterBeanDiscovery, %s", claims));
- installClaimValueProducerMethodsViaSyntheticBeans(event, beanManager);
-
- //installClaimValueProducesViaTemplateType(event, beanManager);
- }
+ final Set<Type> providerTypes = injectionPoints.stream()
+ .filter(NOT_PROVIDERS.negate())
+ .map(ip -> ((ParameterizedType)ip.getType()).getActualTypeArguments()[0])
+ .collect(Collectors.toSet());
- /**
- * Create a synthetic bean with a custom Producer for the non-Provider injection sites.
- *
- * @param event - AfterBeanDiscovery
- * @param beanManager - CDI bean manager
- */
- private void installClaimValueProducerMethodsViaSyntheticBeans(final AfterBeanDiscovery event, final BeanManager beanManager) {
+ types.addAll(providerTypes);
+ types.stream()
+ .map(type -> new ClaimBean<>(bm, type))
+ .forEach(abd::addBean);
}
- private boolean optionalOrJsonValue(Type type) {
- boolean isOptionOrJson = type.getTypeName().startsWith(Optional.class.getTypeName())
- | type.getTypeName().startsWith("javax.json.Json");
- return isOptionOrJson;
+ public void validate(@Observes final AfterDeploymentValidation add) {
+ // not sure yet if we can eagerly check
}
- private boolean isRawParameterizedType(Type type) {
- boolean isRawParameterizedType = false;
- if (type instanceof ParameterizedType) {
- ParameterizedType ptype = ParameterizedType.class.cast(type);
- Type rawType = ptype.getRawType();
- String rawTypeName = rawType.getTypeName();
- isRawParameterizedType = !rawTypeName.startsWith("org.eclipse.microprofile.jwt");
- }
- return isRawParameterizedType;
- }
-
- /**
- * A key for a claim,injection site type pair
- */
- public static class ClaimIPType implements Comparable<ClaimIPType> {
- private String claimName;
- private Type ipType;
-
- public ClaimIPType(String claimName, Type ipType) {
- this.claimName = claimName;
- this.ipType = ipType;
- }
-
- /**
- * Order the @Claim ClaimValue<T> on the @Claim.value and then T type name
- *
- * @param o - ClaimIP to compare to
- * @return the ordering of this claim relative to o
- */
- @Override
- public int compareTo(ClaimIPType o) {
- int compareTo = claimName.compareTo(o.claimName);
- if (compareTo == 0) {
- compareTo = ipType.getTypeName().compareTo(o.ipType.getTypeName());
- }
- return compareTo;
- }
+ public void observeBeforeBeanDiscovery(@Observes final BeforeBeanDiscovery bbd, final BeanManager beanManager) {
+ bbd.addAnnotatedType(beanManager.createAnnotatedType(TCKTokenParser.class));
+ bbd.addAnnotatedType(beanManager.createAnnotatedType(JsonbProducer.class));
+ bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTFilter.class));
+ bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTInitializer.class));
+ bbd.addAnnotatedType(beanManager.createAnnotatedType(JWTAuthContextInfoProvider.class));
+ bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTProducer.class));
}
- /**
- * The representation of an @Claim annotated injection site
- */
- public static class ClaimIP {
- /**
- * The injection site value type
- */
- private Type matchType;
- /**
- * The actual type of of the ParameterizedType matchType
- */
- private Type valueType;
- /**
- * Is valueType actually wrapped in an Optional
- */
- private boolean isOptional;
- private boolean isProviderSite;
- private boolean isNonStandard;
- private boolean isJsonValue;
- /**
- * The injection site @Claim annotation value
- */
- private Claim claim;
- /**
- * The location that share the @Claim/type combination
- */
- private HashSet<InjectionPoint> injectionPoints = new HashSet<>();
-
- /**
- * Create a ClaimIP from the injection site information
- *
- * @param matchType - the outer type of the injection site
- * @param valueType - the parameterized type of the injection site
- * @param isOptional - is the injection site an Optional
- * @param claim - the Claim qualifier
- */
- public ClaimIP(Type matchType, Type valueType, boolean isOptional, Claim claim) {
- this.matchType = matchType;
- this.valueType = valueType;
- this.claim = claim;
- }
-
- public Type getMatchType() {
- return matchType;
- }
-
- public String getClaimName() {
- return claim.standard() == Claims.UNKNOWN ? claim.value() : claim.standard().name();
- }
-
- public Claim getClaim() {
- return claim;
- }
-
- public Type getValueType() {
- return valueType;
- }
-
- public boolean isOptional() {
- return isOptional;
- }
-
- public boolean isProviderSite() {
- return isProviderSite;
- }
-
- public void setProviderSite(boolean providerSite) {
- this.isProviderSite = providerSite;
- }
-
- public boolean isNonStandard() {
- return isNonStandard;
- }
-
- public void setNonStandard(boolean nonStandard) {
- isNonStandard = nonStandard;
- }
-
- public boolean isJsonValue() {
- return isJsonValue;
- }
-
- public void setJsonValue(boolean jsonValue) {
- isJsonValue = jsonValue;
- }
-
- public Set<InjectionPoint> getInjectionPoints() {
- return injectionPoints;
- }
-
- @Override
- public String toString() {
- return "ClaimIP{" +
- "type=" + matchType +
- ", claim=" + claim +
- ", ips=" + injectionPoints +
- '}';
- }
- }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/d81bd39d/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
index 16876fb..1d83a08 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
@@ -16,18 +16,22 @@
*/
package org.apache.tomee.microprofile.jwt.cdi;
+import org.eclipse.microprofile.jwt.Claim;
import org.eclipse.microprofile.jwt.ClaimValue;
+import org.eclipse.microprofile.jwt.Claims;
import org.eclipse.microprofile.jwt.JsonWebToken;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.spi.InjectionPoint;
import javax.inject.Inject;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObject;
import javax.json.JsonValue;
import javax.json.bind.Jsonb;
+import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
http://git-wip-us.apache.org/repos/asf/tomee/blob/d81bd39d/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/RawClaimTypeProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/RawClaimTypeProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/RawClaimTypeProducer.java
deleted file mode 100644
index fbc037b..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/RawClaimTypeProducer.java
+++ /dev/null
@@ -1,80 +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.tomee.microprofile.jwt.cdi;
-
-import org.eclipse.microprofile.jwt.Claim;
-import org.eclipse.microprofile.jwt.ClaimValue;
-import org.eclipse.microprofile.jwt.Claims;
-
-import javax.enterprise.inject.Produces;
-import javax.enterprise.inject.spi.InjectionPoint;
-import javax.inject.Inject;
-import javax.inject.Named;
-import java.lang.annotation.Annotation;
-import java.util.HashSet;
-import java.util.Optional;
-import java.util.Set;
-
-public class RawClaimTypeProducer {
-
- @Inject
- private MPJWTProducer producer;
-
- @Produces
- @Claim("")
- public Set<String> getSetOfString(final InjectionPoint ip) {
- final String name = getName(ip);
- ClaimValue<Optional<String>> cv = producer.generalClaimValueProducer(name);
- Optional<String> value = cv.getValue();
- if (value.isPresent()) {
- return new HashSet<String>() {{
- add(value.get());
- }};
- }
- return null;
- }
-
- @Produces
- @Claim("")
- @Named("RawClaimTypeProducer#getValue")
- public Object getValue(final InjectionPoint ip) {
- String name = getName(ip);
- ClaimValue<Optional<Object>> cv = producer.generalClaimValueProducer(name);
- Optional<Object> value = cv.getValue();
- return value.orElse(null);
- }
-
- @Produces
- @Claim("")
- @Named("RawClaimTypeProducer#getOptionalValue")
- public Optional getOptionalValue(final InjectionPoint ip) {
- String name = getName(ip);
- ClaimValue<Optional<Object>> cv = producer.generalClaimValueProducer(name);
- return cv.getValue();
- }
-
- private String getName(final InjectionPoint ip) {
- String name = null;
- for (Annotation ann : ip.getQualifiers()) {
- if (ann instanceof Claim) {
- Claim claim = (Claim) ann;
- name = claim.standard() == Claims.UNKNOWN ? claim.value() : claim.standard().name();
- }
- }
- return name;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/d81bd39d/tck/mp-jwt-embedded/src/test/resources/dev.xml
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/test/resources/dev.xml b/tck/mp-jwt-embedded/src/test/resources/dev.xml
index 88932f9..b347b26 100644
--- a/tck/mp-jwt-embedded/src/test/resources/dev.xml
+++ b/tck/mp-jwt-embedded/src/test/resources/dev.xml
@@ -42,22 +42,24 @@
</groups>
<classes>
<!-- OK
- -->
<class name="org.eclipse.microprofile.jwt.tck.parsing.TokenValidationTest" />
<class name="org.eclipse.microprofile.jwt.tck.util.TokenUtilsTest" />
<class name="org.eclipse.microprofile.jwt.tck.parsing.TestTokenClaimTypesTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.UnsecuredPingTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.RequiredClaimsTest" />
+ -->
+ <class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.PrimitiveInjectionTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.ClaimValueInjectionTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.JsonValueInjectionTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.ProviderInjectionTest" />
+ <!-- KO
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.RolesAllowedTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.InvalidTokenTest" />
- <!-- KO
-->
</classes>
</test>
+ <!--
<test name="extended-tests" verbose="10">
<groups>
<define name="extended-groups">
@@ -76,14 +78,10 @@
</run>
</groups>
<classes>
- <!-- OK
- -->
<class name="org.eclipse.microprofile.jwt.tck.container.ejb.EjbTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.servlet.ServletTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jacc.SubjectTest" />
- <!-- KO
- -->
</classes>
</test>
-
+ -->
</suite>
[13/38] tomee git commit: Get some code from
https://github.com/MicroProfileJWT/microprofile-jwt-auth-prototype
Posted by jl...@apache.org.
Get some code from https://github.com/MicroProfileJWT/microprofile-jwt-auth-prototype
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/c5b38b37
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/c5b38b37
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/c5b38b37
Branch: refs/heads/master
Commit: c5b38b37142af58fe771d7a397b388cec847f734
Parents: d987d3a
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Thu Feb 22 22:19:49 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Thu Feb 22 22:19:49 2018 +0100
----------------------------------------------------------------------
tck/mp-jwt-embedded/pom.xml | 15 +
.../jwt/DefaultJWTCallerPrincipal.java | 305 ++++++++++++++++++-
.../jwt/DefaultJWTCallerPrincipalFactory.java | 86 ++++++
.../microprofile/jwt/JWTAuthContextInfo.java | 66 ++++
.../microprofile/jwt/JWTCallerPrincipal.java | 9 +-
.../jwt/JWTCallerPrincipalFactory.java | 124 ++++++++
.../tomee/microprofile/jwt/MPJWTContext.java | 3 -
.../tomee/microprofile/jwt/MPJWTFilter.java | 10 +-
.../tomee/microprofile/jwt/ParseException.java | 32 ++
...file.jwt.principal.JWTCallerPrincipalFactory | 1 +
10 files changed, 632 insertions(+), 19 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5b38b37/tck/mp-jwt-embedded/pom.xml
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/pom.xml b/tck/mp-jwt-embedded/pom.xml
index 361fd50..fac5766 100644
--- a/tck/mp-jwt-embedded/pom.xml
+++ b/tck/mp-jwt-embedded/pom.xml
@@ -86,6 +86,21 @@
<version>${version.arquillian}</version>
</dependency>
+ <dependency>
+ <groupId>org.bitbucket.b_c</groupId>
+ <artifactId>jose4j</artifactId>
+ <version>0.6.0</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.json.bind</groupId>
+ <artifactId>javax.json.bind-api</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish</groupId>
+ <artifactId>javax.json</artifactId>
+ <version>1.0.4</version>
+ </dependency>
</dependencies>
<build>
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5b38b37/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/DefaultJWTCallerPrincipal.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/DefaultJWTCallerPrincipal.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/DefaultJWTCallerPrincipal.java
index d141a5f..2559b1e 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/DefaultJWTCallerPrincipal.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/DefaultJWTCallerPrincipal.java
@@ -16,36 +16,319 @@
*/
package org.apache.tomee.microprofile.jwt;
+import org.eclipse.microprofile.jwt.Claims;
+import org.jose4j.jwt.JwtClaims;
+import org.jose4j.jwt.MalformedClaimException;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonNumber;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+import javax.json.JsonValue;
+import javax.security.auth.Subject;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
/**
- * A default implementation of JWTCallerPrincipal that wraps Nimbus library used by default here
- * We could create another implementation using plain JSON-P
- *
+ * A default implementation of JWTCallerPrincipal using jose4j
+ * Another implementation could use nimbus and another plain JSON-P
*/
public class DefaultJWTCallerPrincipal extends JWTCallerPrincipal {
+ private static Logger logger = Logger.getLogger(DefaultJWTCallerPrincipal.class.getName());
+ private String jwt;
+ private String type;
+ private JwtClaims claimsSet;
+
/**
- * Create a JWTCallerPrincipal with the caller's name
+ * Create the DefaultJWTCallerPrincipal from the parsed JWT token and the extracted principal name
*
- * @param name - caller's name
+ * @param jwt - the parsed JWT token representation
+ * @param name - the extracted unqiue name to use as the principal name; from "upn", "preferred_username" or "sub" claim
*/
- public DefaultJWTCallerPrincipal(final String name) {
+ public DefaultJWTCallerPrincipal(String jwt, String type, JwtClaims claimsSet, String name) {
super(name);
+ this.jwt = jwt;
+ this.type = type;
+ this.claimsSet = claimsSet;
+ fixJoseTypes();
+ }
+
+ @Override
+ public Set<String> getAudience() {
+ Set<String> audSet = new HashSet<>();
+ try {
+ List<String> audList = claimsSet.getStringListClaimValue("aud");
+ if (audList != null) {
+ audSet.addAll(audList);
+ }
+ } catch (MalformedClaimException e) {
+ try {
+ String aud = claimsSet.getStringClaimValue("aud");
+ audSet.add(aud);
+ } catch (MalformedClaimException e1) {
+ }
+ }
+ return audSet;
}
@Override
- public String toString(final boolean showAll) {
- return null;
+ public Set<String> getGroups() {
+ HashSet<String> groups = new HashSet<>();
+ try {
+ List<String> globalGroups = claimsSet.getStringListClaimValue("groups");
+ if (globalGroups != null) {
+ groups.addAll(globalGroups);
+ }
+ } catch (MalformedClaimException e) {
+ e.printStackTrace();
+ }
+ return groups;
}
+
@Override
public Set<String> getClaimNames() {
- return null;
+ return new HashSet<>(claimsSet.getClaimNames());
+ }
+
+ @Override
+ public Object getClaim(String claimName) {
+ Claims claimType = Claims.UNKNOWN;
+ Object claim = null;
+ try {
+ claimType = Claims.valueOf(claimName);
+ } catch (IllegalArgumentException e) {
+ }
+ // Handle the jose4j NumericDate types and
+ switch (claimType) {
+ case exp:
+ case iat:
+ case auth_time:
+ case nbf:
+ case updated_at:
+ try {
+ claim = claimsSet.getClaimValue(claimType.name(), Long.class);
+ if (claim == null) {
+ claim = new Long(0);
+ }
+ } catch (MalformedClaimException e) {
+ }
+ break;
+ case groups:
+ claim = getGroups();
+ break;
+ case aud:
+ claim = getAudience();
+ break;
+ case UNKNOWN:
+ claim = claimsSet.getClaimValue(claimName);
+ break;
+ default:
+ claim = claimsSet.getClaimValue(claimType.name());
+ }
+ return claim;
}
@Override
- public <T> T getClaim(final String claimName) {
- return null;
+ public boolean implies(Subject subject) {
+ return false;
+ }
+
+ public String toString() {
+ return toString(false);
}
+
+ /**
+ * TODO: showAll is ignored and currently assumed true
+ *
+ * @param showAll - should all claims associated with the JWT be displayed or should only those defined in the
+ * JsonWebToken interface be displayed.
+ * @return JWTCallerPrincipal string view
+ */
+ @Override
+ public String toString(boolean showAll) {
+ String toString = "DefaultJWTCallerPrincipal{" +
+ "id='" + getTokenID() + '\'' +
+ ", name='" + getName() + '\'' +
+ ", expiration=" + getExpirationTime() +
+ ", notBefore=" + getClaim(Claims.nbf.name()) +
+ ", issuedAt=" + getIssuedAtTime() +
+ ", issuer='" + getIssuer() + '\'' +
+ ", audience=" + getAudience() +
+ ", subject='" + getSubject() + '\'' +
+ ", type='" + type + '\'' +
+ ", issuedFor='" + getClaim("azp") + '\'' +
+ ", authTime=" + getClaim("auth_time") +
+ ", givenName='" + getClaim("given_name") + '\'' +
+ ", familyName='" + getClaim("family_name") + '\'' +
+ ", middleName='" + getClaim("middle_name") + '\'' +
+ ", nickName='" + getClaim("nickname") + '\'' +
+ ", preferredUsername='" + getClaim("preferred_username") + '\'' +
+ ", email='" + getClaim("email") + '\'' +
+ ", emailVerified=" + getClaim(Claims.email_verified.name()) +
+ ", allowedOrigins=" + getClaim("allowedOrigins") +
+ ", updatedAt=" + getClaim("updated_at") +
+ ", acr='" + getClaim("acr") + '\'';
+ StringBuilder tmp = new StringBuilder(toString);
+ tmp.append(", groups=[");
+ for (String group : getGroups()) {
+ tmp.append(group);
+ tmp.append(',');
+ }
+ tmp.setLength(tmp.length() - 1);
+ tmp.append("]}");
+ return tmp.toString();
+ }
+
+ /**
+ * Convert the types jose4j uses for address, sub_jwk, and jwk
+ */
+ private void fixJoseTypes() {
+ if (claimsSet.hasClaim(Claims.address.name())) {
+ replaceMap(Claims.address.name());
+ }
+ if (claimsSet.hasClaim(Claims.jwk.name())) {
+ replaceMap(Claims.jwk.name());
+ }
+ if (claimsSet.hasClaim(Claims.sub_jwk.name())) {
+ replaceMap(Claims.sub_jwk.name());
+ }
+ // Handle custom claims
+ Set<String> customClaimNames = filterCustomClaimNames(claimsSet.getClaimNames());
+ for (String name : customClaimNames) {
+ Object claimValue = claimsSet.getClaimValue(name);
+ Class claimType = claimValue.getClass();
+ if (claimValue instanceof List) {
+ replaceList(name);
+ } else if (claimValue instanceof Map) {
+ replaceMap(name);
+ } else if (claimValue instanceof Number) {
+ replaceNumber(name);
+ }
+ }
+ }
+
+ /**
+ * Determine the custom claims in the set
+ *
+ * @param claimNames - the current set of claim names in this token
+ * @return the possibly empty set of names for non-Claims claims
+ */
+ private Set<String> filterCustomClaimNames(Collection<String> claimNames) {
+ HashSet<String> customNames = new HashSet<>(claimNames);
+ for (Claims claim : Claims.values()) {
+ customNames.remove(claim.name());
+ }
+ return customNames;
+ }
+
+ /**
+ * Replace the jose4j Map<String,Object> with a JsonObject
+ *
+ * @param name - claim name
+ */
+ private void replaceMap(String name) {
+ try {
+ Map<String, Object> map = claimsSet.getClaimValue(name, Map.class);
+ JsonObject jsonObject = replaceMap(map);
+ claimsSet.setClaim(name, jsonObject);
+ } catch (MalformedClaimException e) {
+ logger.log(Level.WARNING, "replaceMap failure for: " + name, e);
+ }
+ }
+
+ private JsonObject replaceMap(Map<String, Object> map) {
+ JsonObjectBuilder builder = Json.createObjectBuilder();
+ for (Map.Entry<String, Object> entry : map.entrySet()) {
+ Object entryValue = entry.getValue();
+ if (entryValue instanceof Map) {
+ JsonObject entryJsonObject = replaceMap((Map<String, Object>) entryValue);
+ builder.add(entry.getKey(), entryJsonObject);
+ } else if (entryValue instanceof List) {
+ JsonArray array = (JsonArray) wrapValue(entryValue);
+ builder.add(entry.getKey(), array);
+ } else if (entryValue instanceof Long || entryValue instanceof Integer) {
+ long lvalue = ((Number) entryValue).longValue();
+ builder.add(entry.getKey(), lvalue);
+ } else if (entryValue instanceof Double || entryValue instanceof Float) {
+ double dvalue = ((Number) entryValue).doubleValue();
+ builder.add(entry.getKey(), dvalue);
+ } else if (entryValue instanceof Boolean) {
+ boolean flag = ((Boolean) entryValue).booleanValue();
+ builder.add(entry.getKey(), flag);
+ } else if (entryValue instanceof String) {
+ builder.add(entry.getKey(), entryValue.toString());
+ }
+ }
+ return builder.build();
+ }
+
+ private JsonValue wrapValue(Object value) {
+ JsonValue jsonValue = null;
+ if (value instanceof Number) {
+ Number number = (Number) value;
+ if ((number instanceof Long) || (number instanceof Integer)) {
+ jsonValue = Json.createObjectBuilder()
+ .add("tmp", number.longValue())
+ .build()
+ .getJsonNumber("tmp");
+ } else {
+ jsonValue = Json.createObjectBuilder()
+ .add("tmp", number.doubleValue())
+ .build()
+ .getJsonNumber("tmp");
+ }
+ } else if (value instanceof Boolean) {
+ Boolean flag = (Boolean) value;
+ jsonValue = flag ? JsonValue.TRUE : JsonValue.FALSE;
+ } else if (value instanceof List) {
+ JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
+ List list = (List) value;
+ for (Object element : list) {
+ if (element instanceof String) {
+ arrayBuilder.add(element.toString());
+ } else {
+ JsonValue jvalue = wrapValue(element);
+ arrayBuilder.add(jvalue);
+ }
+ }
+ jsonValue = arrayBuilder.build();
+ }
+ return jsonValue;
+ }
+
+
+ /**
+ * Replace the jose4j List<?> with a JsonArray
+ *
+ * @param name - claim name
+ */
+ private void replaceList(String name) {
+ try {
+ List list = claimsSet.getClaimValue(name, List.class);
+ JsonArray array = (JsonArray) wrapValue(list);
+ claimsSet.setClaim(name, array);
+ } catch (MalformedClaimException e) {
+ logger.log(Level.WARNING, "replaceList failure for: " + name, e);
+ }
+ }
+
+ private void replaceNumber(String name) {
+ try {
+ Number number = claimsSet.getClaimValue(name, Number.class);
+ JsonNumber jsonNumber = (JsonNumber) wrapValue(number);
+ claimsSet.setClaim(name, jsonNumber);
+ } catch (MalformedClaimException e) {
+ logger.log(Level.WARNING, "replaceNumber failure for: " + name, e);
+ }
+ }
+
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5b38b37/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/DefaultJWTCallerPrincipalFactory.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/DefaultJWTCallerPrincipalFactory.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/DefaultJWTCallerPrincipalFactory.java
new file mode 100644
index 0000000..9c0a870
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/DefaultJWTCallerPrincipalFactory.java
@@ -0,0 +1,86 @@
+/*
+ * 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.tomee.microprofile.jwt;
+
+import org.eclipse.microprofile.jwt.Claims;
+import org.jose4j.jwa.AlgorithmConstraints;
+import org.jose4j.jws.AlgorithmIdentifiers;
+import org.jose4j.jwt.JwtClaims;
+import org.jose4j.jwt.MalformedClaimException;
+import org.jose4j.jwt.NumericDate;
+import org.jose4j.jwt.consumer.InvalidJwtException;
+import org.jose4j.jwt.consumer.JwtConsumer;
+import org.jose4j.jwt.consumer.JwtConsumerBuilder;
+import org.jose4j.jwt.consumer.JwtContext;
+
+/**
+ * A default implementation of the abstract JWTCallerPrincipalFactory that uses the Keycloak token parsing classes.
+ */
+public class DefaultJWTCallerPrincipalFactory extends JWTCallerPrincipalFactory {
+
+ /**
+ * Tries to load the JWTAuthContextInfo from CDI if the class level authContextInfo has not been set.
+ */
+ public DefaultJWTCallerPrincipalFactory() {
+ }
+
+ @Override
+ public JWTCallerPrincipal parse(final String token, final JWTAuthContextInfo authContextInfo) throws ParseException {
+ JWTCallerPrincipal principal = null;
+
+ try {
+ JwtConsumerBuilder builder = new JwtConsumerBuilder()
+ .setRequireExpirationTime()
+ .setRequireSubject()
+ .setSkipDefaultAudienceValidation()
+ .setExpectedIssuer(authContextInfo.getIssuedBy())
+ .setVerificationKey(authContextInfo.getSignerKey())
+ .setJwsAlgorithmConstraints(
+ new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.WHITELIST,
+ AlgorithmIdentifiers.RSA_USING_SHA256));
+ if (authContextInfo.getExpGracePeriodSecs() > 0) {
+ builder.setAllowedClockSkewInSeconds(authContextInfo.getExpGracePeriodSecs());
+ } else {
+ builder.setEvaluationTime(NumericDate.fromSeconds(0));
+ }
+
+ JwtConsumer jwtConsumer = builder.build();
+ JwtContext jwtContext = jwtConsumer.process(token);
+ String type = jwtContext.getJoseObjects().get(0).getHeader("typ");
+ // Validate the JWT and process it to the Claims
+ jwtConsumer.processContext(jwtContext);
+ JwtClaims claimsSet = jwtContext.getJwtClaims();
+
+ // We have to determine the unique name to use as the principal name. It comes from upn, preferred_username, sub in that order
+ String principalName = claimsSet.getClaimValue("upn", String.class);
+ if (principalName == null) {
+ principalName = claimsSet.getClaimValue("preferred_username", String.class);
+ if (principalName == null) {
+ principalName = claimsSet.getSubject();
+ }
+ }
+ claimsSet.setClaim(Claims.raw_token.name(), token);
+ principal = new DefaultJWTCallerPrincipal(token, type, claimsSet, principalName);
+ } catch (InvalidJwtException e) {
+ throw new ParseException("Failed to verify token", e);
+ } catch (MalformedClaimException e) {
+ throw new ParseException("Failed to verify token claims", e);
+ }
+
+ return principal;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5b38b37/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTAuthContextInfo.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTAuthContextInfo.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTAuthContextInfo.java
new file mode 100644
index 0000000..a93e2cc
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTAuthContextInfo.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.tomee.microprofile.jwt;
+
+import java.security.interfaces.RSAPublicKey;
+
+/**
+ * The public key and expected issuer needed to validate a token.
+ */
+public class JWTAuthContextInfo {
+ private RSAPublicKey signerKey;
+ private String issuedBy;
+ private int expGracePeriodSecs = 60;
+
+ public JWTAuthContextInfo() {
+ }
+
+ public JWTAuthContextInfo(RSAPublicKey signerKey, String issuedBy) {
+ this.signerKey = signerKey;
+ this.issuedBy = issuedBy;
+ }
+
+ public JWTAuthContextInfo(JWTAuthContextInfo orig) {
+ this.signerKey = orig.signerKey;
+ this.issuedBy = orig.issuedBy;
+ this.expGracePeriodSecs = orig.expGracePeriodSecs;
+ }
+
+ public RSAPublicKey getSignerKey() {
+ return signerKey;
+ }
+
+ public void setSignerKey(RSAPublicKey signerKey) {
+ this.signerKey = signerKey;
+ }
+
+ public String getIssuedBy() {
+ return issuedBy;
+ }
+
+ public void setIssuedBy(String issuedBy) {
+ this.issuedBy = issuedBy;
+ }
+
+ public int getExpGracePeriodSecs() {
+ return expGracePeriodSecs;
+ }
+
+ public void setExpGracePeriodSecs(int expGracePeriodSecs) {
+ this.expGracePeriodSecs = expGracePeriodSecs;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5b38b37/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipal.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipal.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipal.java
index 3eca47b..e130213 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipal.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipal.java
@@ -14,18 +14,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.apache.tomee.microprofile.jwt;
-import java.util.Optional;
import org.eclipse.microprofile.jwt.JsonWebToken;
+import java.util.Optional;
+
/**
* An abstract CallerPrincipal implementation that provides access to the JWT claims that are required by
* the microprofile token.
*/
public abstract class JWTCallerPrincipal implements JsonWebToken {
+
private String name;
/**
@@ -51,8 +52,8 @@ public abstract class JWTCallerPrincipal implements JsonWebToken {
*/
public abstract String toString(boolean showAll);
- public <T> Optional<T> claim(String claimName) {
- T claim = (T) getClaim(claimName);
+ public <T> Optional<T> claim(final String claimName) {
+ final T claim = (T) getClaim(claimName);
return Optional.ofNullable(claim);
}
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5b38b37/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipalFactory.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipalFactory.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipalFactory.java
new file mode 100644
index 0000000..a64f95a
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipalFactory.java
@@ -0,0 +1,124 @@
+/*
+ * 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.tomee.microprofile.jwt;
+
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ServiceLoader;
+
+/**
+ * The factory class that provides the token string to JWTCallerPrincipal parsing for a given implementation.
+ */
+public abstract class JWTCallerPrincipalFactory {
+ private static JWTCallerPrincipalFactory instance;
+
+ /**
+ * Obtain the JWTCallerPrincipalFactory that has been set or by using the ServiceLoader pattern.
+ *
+ * @return the factory instance
+ * @see #setInstance(JWTCallerPrincipalFactory)
+ */
+ public static JWTCallerPrincipalFactory instance() {
+ if (instance == null) {
+ synchronized (JWTCallerPrincipalFactory.class) {
+ if (instance != null) {
+ return instance;
+ }
+
+ ClassLoader cl = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+ @Override
+ public ClassLoader run() {
+ return Thread.currentThread().getContextClassLoader();
+ }
+ });
+ if (cl == null) {
+ cl = JWTCallerPrincipalFactory.class.getClassLoader();
+ }
+
+ JWTCallerPrincipalFactory newInstance = loadSpi(cl);
+
+ if (newInstance == null && cl != JWTCallerPrincipalFactory.class.getClassLoader()) {
+ cl = JWTCallerPrincipalFactory.class.getClassLoader();
+ newInstance = loadSpi(cl);
+ }
+ if (newInstance == null) {
+ throw new IllegalStateException("No JWTCallerPrincipalFactory implementation found!");
+ }
+
+ instance = newInstance;
+ }
+ }
+
+ return instance;
+ }
+
+ /**
+ * Look for a JWTCallerPrincipalFactory service implementation using the ServiceLoader.
+ *
+ * @param cl - the ClassLoader to pass into the {@link ServiceLoader#load(Class, ClassLoader)} method.
+ * @return the JWTCallerPrincipalFactory if found, null otherwise
+ */
+ private static JWTCallerPrincipalFactory loadSpi(ClassLoader cl) {
+ if (cl == null) {
+ return null;
+ }
+
+ // start from the root CL and go back down to the TCCL
+ JWTCallerPrincipalFactory instance = loadSpi(cl.getParent());
+
+ if (instance == null) {
+ ServiceLoader<JWTCallerPrincipalFactory> sl = ServiceLoader.load(JWTCallerPrincipalFactory.class, cl);
+ URL u = cl.getResource("/META-INF/services/org.eclipse.microprofile.jwt.principal.JWTCallerPrincipalFactory");
+ System.out.printf("JWTCallerPrincipalFactory, cl=%s, u=%s, sl=%s\n", cl, u, sl);
+ try {
+ for (JWTCallerPrincipalFactory spi : sl) {
+ if (instance != null) {
+ throw new IllegalStateException(
+ "Multiple JWTCallerPrincipalFactory implementations found: "
+ + spi.getClass().getName() + " and "
+ + instance.getClass().getName());
+ } else {
+ System.out.printf("sl=%s, loaded=%s\n", sl, spi);
+ instance = spi;
+ }
+ }
+ } catch (Throwable e) {
+ System.err.printf("Warning: %s\n", e.getMessage());
+ }
+ }
+ return instance;
+ }
+
+ /**
+ * Set the instance. It is used by OSGi environment where service loader pattern is not supported.
+ *
+ * @param resolver the instance to use.
+ */
+ public static void setInstance(JWTCallerPrincipalFactory resolver) {
+ instance = resolver;
+ }
+
+ /**
+ * Parse the given bearer token string into a JWTCallerPrincipal instance.
+ *
+ * @param token - the bearer token provided for authorization
+ * @return A JWTCallerPrincipal representation for the token.
+ * @throws ParseException on parse or verification failure.
+ */
+ public abstract JWTCallerPrincipal parse(String token, JWTAuthContextInfo authContextInfo) throws ParseException;
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5b38b37/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTContext.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTContext.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTContext.java
index 2197745..bffccf2 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTContext.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTContext.java
@@ -16,10 +16,7 @@
*/
package org.apache.tomee.microprofile.jwt;
-import org.eclipse.microprofile.auth.LoginConfig;
-
import javax.enterprise.context.ApplicationScoped;
-import java.net.URI;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5b38b37/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
index cb235fa..092ad9d 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
@@ -40,6 +40,9 @@ public class MPJWTFilter implements Filter {
@Inject
private MPJWTContext context;
+ @Inject
+ private JWTAuthContextInfo authContextInfo;
+
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
// get configuration
@@ -60,7 +63,7 @@ public class MPJWTFilter implements Filter {
// todo get JWT and do validation
// todo not sure what to do with the realm
- final JsonWebToken jsonWebToken = new DefaultJWTCallerPrincipal("bla"); // will be build during validation
+ final JsonWebToken jsonWebToken = null; // will be build during validation
// now wrap the httpServletRequest and override the principal so CXF can propagate into the SecurityContext
chain.doFilter(new HttpServletRequestWrapper(httpServletRequest) {
@@ -89,4 +92,9 @@ public class MPJWTFilter implements Filter {
}
+ protected JsonWebToken validate(String bearerToken) throws ParseException {
+ JWTCallerPrincipalFactory factory = JWTCallerPrincipalFactory.instance();
+ return factory.parse(bearerToken, authContextInfo);
+ }
+
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5b38b37/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ParseException.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ParseException.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ParseException.java
new file mode 100644
index 0000000..60269b0
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ParseException.java
@@ -0,0 +1,32 @@
+/*
+ * 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.tomee.microprofile.jwt;
+
+/**
+ * The exception thrown when
+ */
+public class ParseException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ public ParseException(String message) {
+ super(message);
+ }
+
+ public ParseException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5b38b37/tck/mp-jwt-embedded/src/main/resources/META-INF/services/org.eclipse.microprofile.jwt.principal.JWTCallerPrincipalFactory
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/resources/META-INF/services/org.eclipse.microprofile.jwt.principal.JWTCallerPrincipalFactory b/tck/mp-jwt-embedded/src/main/resources/META-INF/services/org.eclipse.microprofile.jwt.principal.JWTCallerPrincipalFactory
new file mode 100644
index 0000000..67f39db
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/resources/META-INF/services/org.eclipse.microprofile.jwt.principal.JWTCallerPrincipalFactory
@@ -0,0 +1 @@
+org.apache.tomee.microprofile.jwt.DefaultJWTCallerPrincipalFactory
\ No newline at end of file
[25/38] tomee git commit: Handling most of the injections. Missing
Provider and Instance for now and then a couple of failures with
@RolesAllowed and JACC
Posted by jl...@apache.org.
Handling most of the injections. Missing Provider and Instance for now and then a couple of failures with @RolesAllowed and JACC
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/b05e5643
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/b05e5643
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/b05e5643
Branch: refs/heads/master
Commit: b05e5643dd976ecbc7509ac634f4a35f7f9b95f0
Parents: 92846ae
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Fri Mar 2 15:04:59 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Fri Mar 2 15:04:59 2018 +0100
----------------------------------------------------------------------
.../tomee/microprofile/jwt/MPJWTFilter.java | 6 +-
.../tomee/microprofile/jwt/cdi/ClaimBean.java | 159 +++++++++++++++++--
tck/mp-jwt-embedded/src/test/resources/dev.xml | 10 +-
3 files changed, 152 insertions(+), 23 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/b05e5643/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
index ebed96d..36e53cf 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
@@ -84,9 +84,9 @@ public class MPJWTFilter implements Filter {
jsonWebToken = validate(token);
} catch (final ParseException e) {
- // todo properly handle the exception as required per spec
- e.printStackTrace();
- throw new RuntimeException(e);
+ // todo is this enough?
+ HttpServletResponse.class.cast(response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
+ return;
}
// associate with the producer. Should not be needed.
http://git-wip-us.apache.org/repos/asf/tomee/blob/b05e5643/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
index 10abedf..0e87404 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
@@ -23,18 +23,28 @@ import org.eclipse.microprofile.jwt.JsonWebToken;
import javax.enterprise.context.Dependent;
import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.Instance;
import javax.enterprise.inject.spi.Annotated;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.enterprise.inject.spi.PassivationCapable;
+import javax.enterprise.util.AnnotationLiteral;
+import javax.inject.Inject;
import javax.inject.Provider;
+import javax.json.Json;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonObject;
+import javax.json.JsonValue;
+import javax.json.bind.Jsonb;
import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.logging.Logger;
@@ -45,6 +55,13 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
private final static Set<Annotation> QUALIFIERS = new HashSet<>();
+ static {
+ QUALIFIERS.add(new ClaimLiteral());
+ }
+
+ @Inject
+ private Jsonb jsonb;
+
private final BeanManager bm;
private final Class rawType;
private final Set<Type> types;
@@ -140,7 +157,7 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
final String key = getClaimKey(claim);
System.out.println(String.format("Found Claim injection with name=%s and for InjectionPoint=%s", key, ip.toString()));
- logger.finest(String.format("Found Claim injection with name=%s and for InjectionPoint=%s", key, ip.toString()));
+ logger.finest(String.format("Found Claim injection with name=%s and for %s", key, ip.toString()));
if (annotated.getBaseType() instanceof ParameterizedType) {
final ParameterizedType paramType = (ParameterizedType) annotated.getBaseType();
@@ -151,39 +168,65 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
// handle Provider<T>
if (rawTypeClass.isAssignableFrom(Provider.class)) {
- final Class clazz = (Class) paramType.getActualTypeArguments()[0]; //X TODO check type again, etc
- return (T) getClaimValue(key, clazz);
+ return getClaimValue(key);
+ }
+
+ // handle Instance<T>
+ if (rawTypeClass.isAssignableFrom(Instance.class)) {
+ return getClaimValue(key);
}
// handle ClaimValue<T>
if (rawTypeClass.isAssignableFrom(ClaimValue.class)) {
- final Class clazz = (Class) paramType.getActualTypeArguments()[0]; //X TODO check type again, etc
- return (T) getClaimValue(key, clazz);
+ final Type claimValueType = paramType.getActualTypeArguments()[0];
+
+ final ClaimValueWrapper claimValueWrapper = new ClaimValueWrapper(key);
+ if (claimValueType instanceof ParameterizedType && isOptional((ParameterizedType) claimValueType)) {
+ final T claimValue = getClaimValue(key);
+ claimValueWrapper.setValue(Optional.ofNullable(claimValue));
+
+ } else if (claimValueType instanceof ParameterizedType && isSet((ParameterizedType) claimValueType)) {
+ final T claimValue = getClaimValue(key);
+ claimValueWrapper.setValue(claimValue); // todo convert to set
+
+ } else if (claimValueType instanceof ParameterizedType && isList((ParameterizedType) claimValueType)) {
+ final T claimValue = getClaimValue(key);
+ claimValueWrapper.setValue(claimValue); // // todo convert to list
+
+ } else if (claimValueType instanceof Class) {
+ final T claimValue = getClaimValue(key);
+ claimValueWrapper.setValue(claimValue);
+
+ } else {
+ throw new IllegalArgumentException("Unsupported ClaimValue type " + claimValueType.toString());
+ }
+
+ return (T) claimValueWrapper;
}
// handle Optional<T>
if (rawTypeClass.isAssignableFrom(Optional.class)) {
- final Class clazz = (Class) paramType.getActualTypeArguments()[0]; //X TODO check type again, etc
- return (T) getClaimValue(key, clazz);
+ return getClaimValue(key);
}
// handle Set<T>
if (rawTypeClass.isAssignableFrom(Set.class)) {
- Class clazz = (Class) paramType.getActualTypeArguments()[0]; //X TODO check type again, etc
- return getClaimValue(key, clazz);
+ return getClaimValue(key);
}
// handle List<T>
if (rawTypeClass.isAssignableFrom(List.class)) {
- final Class clazz = (Class) paramType.getActualTypeArguments()[0]; //X TODO check type again, etc
- return getClaimValue(key, clazz);
+ return getClaimValue(key);
}
}
+ } else if (annotated.getBaseType().getTypeName().startsWith("javax.json.Json")) {
+ // handle JsonValue<T> (number, string, etc)
+ return (T) toJson(key);
+
} else {
// handle Raw types
- final Class clazz = (Class) annotated.getBaseType();
- return getClaimValue(key, clazz);
+ return getClaimValue(key);
}
throw new IllegalStateException("Unhandled ClaimValue type");
@@ -193,7 +236,7 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
return claim.standard() == Claims.UNKNOWN ? claim.value() : claim.standard().name();
}
- private T getClaimValue(final String name, final Class clazz) {
+ private T getClaimValue(final String name) {
final JsonWebToken jwt = MPJWTProducer.getJWTPrincipal();
if (jwt == null) {
logger.warning(String.format("Can't retrieve claim %s. No active principal.", name));
@@ -202,7 +245,93 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
final Optional<T> claimValue = jwt.claim(name);
logger.finest(String.format("Found ClaimValue=%s for name=%s", claimValue, name));
- return claimValue.orElse(null); // todo more to do?
+ return claimValue.orElse(null);
+ }
+
+ private JsonValue toJson(final String name) {
+ final T claimValue = getClaimValue(name);
+ return wrapValue(claimValue);
+ }
+
+ private static final String TMP = "tmp"; // todo kill this if possible
+
+ private JsonValue wrapValue(Object value) {
+ JsonValue jsonValue = null;
+
+ if (value instanceof JsonValue) {
+ // This may already be a JsonValue
+ jsonValue = (JsonValue) value;
+
+ } else if (value instanceof String) {
+ jsonValue = Json.createObjectBuilder()
+ .add(TMP, value.toString())
+ .build()
+ .getJsonString(TMP);
+
+ } else if (value instanceof Number) {
+ final Number number = (Number) value;
+ if ((number instanceof Long) || (number instanceof Integer)) {
+ jsonValue = Json.createObjectBuilder()
+ .add(TMP, number.longValue())
+ .build()
+ .getJsonNumber(TMP);
+
+ } else {
+ jsonValue = Json.createObjectBuilder()
+ .add(TMP, number.doubleValue())
+ .build()
+ .getJsonNumber(TMP);
+ }
+
+ } else if (value instanceof Boolean) {
+ final Boolean flag = (Boolean) value;
+ jsonValue = flag ? JsonValue.TRUE : JsonValue.FALSE;
+
+ } else if (value instanceof Collection) {
+ final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
+ final Collection list = (Collection) value;
+
+ for (Object element : list) {
+ if (element instanceof String) {
+ arrayBuilder.add(element.toString());
+
+ } else {
+ final JsonValue jvalue = wrapValue(element);
+ arrayBuilder.add(jvalue);
+ }
+ }
+ jsonValue = arrayBuilder.build();
+
+ } else if (value instanceof Map) {
+ jsonValue = jsonb.fromJson(jsonb.toJson(value), JsonObject.class);
+
+ }
+ return jsonValue;
+ }
+
+ private boolean isOptional(final ParameterizedType type) {
+ return ((Class) type.getRawType()).isAssignableFrom(Optional.class);
+ }
+
+ private boolean isSet(final ParameterizedType type) {
+ return ((Class) type.getRawType()).isAssignableFrom(Set.class);
+ }
+
+ private boolean isList(final ParameterizedType type) {
+ return ((Class) type.getRawType()).isAssignableFrom(List.class);
+ }
+
+ private static class ClaimLiteral extends AnnotationLiteral<Claim> implements Claim {
+
+ @Override
+ public String value() {
+ return "";
+ }
+
+ @Override
+ public Claims standard() {
+ return Claims.UNKNOWN;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/b05e5643/tck/mp-jwt-embedded/src/test/resources/dev.xml
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/test/resources/dev.xml b/tck/mp-jwt-embedded/src/test/resources/dev.xml
index b347b26..27205d2 100644
--- a/tck/mp-jwt-embedded/src/test/resources/dev.xml
+++ b/tck/mp-jwt-embedded/src/test/resources/dev.xml
@@ -42,24 +42,24 @@
</groups>
<classes>
<!-- OK
+ -->
<class name="org.eclipse.microprofile.jwt.tck.parsing.TokenValidationTest" />
<class name="org.eclipse.microprofile.jwt.tck.util.TokenUtilsTest" />
<class name="org.eclipse.microprofile.jwt.tck.parsing.TestTokenClaimTypesTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.UnsecuredPingTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.RequiredClaimsTest" />
- -->
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.PrimitiveInjectionTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.ClaimValueInjectionTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.JsonValueInjectionTest" />
- <class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.ProviderInjectionTest" />
- <!-- KO
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.RolesAllowedTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.InvalidTokenTest" />
+ <!-- KO
+ <class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.ProviderInjectionTest" />
-->
</classes>
</test>
- <!--
+
<test name="extended-tests" verbose="10">
<groups>
<define name="extended-groups">
@@ -83,5 +83,5 @@
<class name="org.eclipse.microprofile.jwt.tck.container.jacc.SubjectTest" />
</classes>
</test>
- -->
+
</suite>
[16/38] tomee git commit: Add more implementations and TCK coverage
Posted by jl...@apache.org.
Add more implementations and TCK coverage
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/830b3729
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/830b3729
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/830b3729
Branch: refs/heads/master
Commit: 830b372981330bf028b576b155e497b24c85bf9a
Parents: 9c69190
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Tue Feb 27 09:16:44 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Tue Feb 27 09:16:44 2018 +0100
----------------------------------------------------------------------
tck/mp-jwt-embedded/pom.xml | 11 +
.../tomee/microprofile/jwt/ClaimLiteral.java | 32 ++
.../jwt/ClaimProviderBeanAttributes.java | 83 ++++
.../microprofile/jwt/ClaimValueProducer.java | 75 ++++
.../microprofile/jwt/ClaimValueWrapper.java | 54 +++
.../jwt/JWTAuthContextInfoProvider.java | 59 +++
.../jwt/JWTCallerPrincipalFactory.java | 2 +-
.../microprofile/jwt/JsonValueProducer.java | 111 ++++++
.../apache/tomee/microprofile/jwt/KeyUtils.java | 84 ++++
.../microprofile/jwt/MPJWTCDIExtension.java | 391 +++++++++++++++++++
.../tomee/microprofile/jwt/MPJWTContext.java | 9 +-
.../tomee/microprofile/jwt/MPJWTFilter.java | 25 +-
.../microprofile/jwt/MPJWTInitializer.java | 7 +-
.../tomee/microprofile/jwt/MPJWTProducer.java | 196 ++++++++++
.../microprofile/jwt/RawClaimTypeProducer.java | 69 ++++
.../javax.enterprise.inject.spi.Extension | 1 +
...e.microprofile.jwt.JWTCallerPrincipalFactory | 1 +
...file.jwt.principal.JWTCallerPrincipalFactory | 1 -
.../jwt/AppDeploymentExtension.java | 37 ++
....jboss.arquillian.core.spi.LoadableExtension | 1 +
tck/mp-jwt-embedded/src/test/resources/dev.xml | 8 +-
21 files changed, 1237 insertions(+), 20 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/830b3729/tck/mp-jwt-embedded/pom.xml
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/pom.xml b/tck/mp-jwt-embedded/pom.xml
index ddbccec..272f4ad 100644
--- a/tck/mp-jwt-embedded/pom.xml
+++ b/tck/mp-jwt-embedded/pom.xml
@@ -112,6 +112,16 @@
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.6.1</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>JwSecTest
+ </configuration>
+ </plugin>
+ <!--
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
@@ -136,6 +146,7 @@
</execution>
</executions>
</plugin>
+ -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
http://git-wip-us.apache.org/repos/asf/tomee/blob/830b3729/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimLiteral.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimLiteral.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimLiteral.java
new file mode 100644
index 0000000..5471b2e
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimLiteral.java
@@ -0,0 +1,32 @@
+/*
+ * 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.tomee.microprofile.jwt;
+
+import javax.enterprise.util.AnnotationLiteral;
+
+import org.eclipse.microprofile.jwt.Claim;
+import org.eclipse.microprofile.jwt.Claims;
+
+public class ClaimLiteral extends AnnotationLiteral<Claim> implements Claim {
+ public String value() {
+ return "";
+ }
+
+ public Claims standard() {
+ return Claims.UNKNOWN;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/830b3729/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimProviderBeanAttributes.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimProviderBeanAttributes.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimProviderBeanAttributes.java
new file mode 100644
index 0000000..ce6e97c
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimProviderBeanAttributes.java
@@ -0,0 +1,83 @@
+/*
+ * 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.tomee.microprofile.jwt;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Set;
+
+import javax.enterprise.inject.spi.BeanAttributes;
+
+/**
+ * An implementation of BeanAttributes<Object> that wraps the generic producer BeanAttributes
+ * to allow the MPJWTExtension to collect the types of all corresponding injection sites
+ *
+ */
+public class ClaimProviderBeanAttributes implements BeanAttributes<Object> {
+ /**
+ * Decorate the ConfigPropertyProducer BeanAttributes to set the types the producer applies to. This set is collected
+ * from all injection points annotated with @ConfigProperty.
+ *
+ * @param delegate - the original producer method BeanAttributes
+ * @param types - the full set of @Claim injection point types
+ */
+ public ClaimProviderBeanAttributes(BeanAttributes<Object> delegate, Set<Type> types, Set<Annotation> qualifiers) {
+ this.delegate = delegate;
+ this.types = types;
+ this.qualifiers = qualifiers;
+ if (types.size() == 0) {
+ Thread.dumpStack();
+ }
+ }
+
+ @Override
+ public Set<Type> getTypes() {
+ return types;
+ }
+
+ @Override
+ public Set<Annotation> getQualifiers() {
+ return qualifiers;
+ }
+
+ @Override
+ public Class<? extends Annotation> getScope() {
+ return delegate.getScope();
+ }
+
+ @Override
+ public String getName() {
+ return delegate.getName();
+ }
+
+ @Override
+ public Set<Class<? extends Annotation>> getStereotypes() {
+ return delegate.getStereotypes();
+ }
+
+ @Override
+ public boolean isAlternative() {
+ return delegate.isAlternative();
+ }
+
+ private BeanAttributes<Object> delegate;
+
+ private Set<Type> types;
+
+ private Set<Annotation> qualifiers;
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/830b3729/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimValueProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimValueProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimValueProducer.java
new file mode 100644
index 0000000..ae2338f
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimValueProducer.java
@@ -0,0 +1,75 @@
+/*
+ * 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.tomee.microprofile.jwt;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Optional;
+
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.spi.InjectionPoint;
+
+import org.eclipse.microprofile.jwt.Claim;
+import org.eclipse.microprofile.jwt.ClaimValue;
+import org.eclipse.microprofile.jwt.Claims;
+
+/**
+ * A producer for the ClaimValue<T> wrapper injection sites.
+ * @param <T> the raw claim type
+ */
+public class ClaimValueProducer<T> {
+
+ @Produces
+ @Claim("")
+ ClaimValue<T> produce(InjectionPoint ip) {
+ String name = getName(ip);
+ ClaimValue<Optional<T>> cv = MPJWTProducer.generalClaimValueProducer(name);
+ ClaimValue<T> returnValue = (ClaimValue<T>) cv;
+ Optional<T> value = cv.getValue();
+ // Pull out the ClaimValue<T> T type,
+ Type matchType = ip.getType();
+ Type actualType = Object.class;
+ boolean isOptional = false;
+ if (matchType instanceof ParameterizedType) {
+ actualType = ((ParameterizedType) matchType).getActualTypeArguments()[0];
+ isOptional = matchType.getTypeName().equals(Optional.class.getTypeName());
+ if (isOptional) {
+ actualType = ((ParameterizedType) matchType).getActualTypeArguments()[0];
+ }
+ }
+
+ if (!actualType.getTypeName().startsWith(Optional.class.getTypeName())) {
+ T nestedValue = value.orElse(null);
+ ClaimValueWrapper<T> wrapper = new ClaimValueWrapper<>(cv.getName());
+ wrapper.setValue(nestedValue);
+ returnValue = wrapper;
+ }
+ return returnValue;
+ }
+
+ String getName(InjectionPoint ip) {
+ String name = null;
+ for (Annotation ann : ip.getQualifiers()) {
+ if (ann instanceof Claim) {
+ Claim claim = (Claim) ann;
+ name = claim.standard() == Claims.UNKNOWN ? claim.value() : claim.standard().name();
+ }
+ }
+ return name;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/830b3729/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimValueWrapper.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimValueWrapper.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimValueWrapper.java
new file mode 100644
index 0000000..cc16771
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimValueWrapper.java
@@ -0,0 +1,54 @@
+/*
+ * 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.tomee.microprofile.jwt;
+
+import org.eclipse.microprofile.jwt.ClaimValue;
+
+/**
+ * An implementation of the ClaimValue interface
+ *
+ * @param <T> the claim value type
+ */
+public class ClaimValueWrapper<T> implements ClaimValue<T> {
+ private String name;
+
+ private T value;
+
+ public ClaimValueWrapper(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public T getValue() {
+ return value;
+ }
+
+ public void setValue(T value) {
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("ClaimValueWrapper[@%s], name=%s, value[%s]=%s", Integer.toHexString(hashCode()),
+ name, value.getClass(), value);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/830b3729/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTAuthContextInfoProvider.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTAuthContextInfoProvider.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTAuthContextInfoProvider.java
new file mode 100644
index 0000000..a173ea2
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTAuthContextInfoProvider.java
@@ -0,0 +1,59 @@
+/*
+ * 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.tomee.microprofile.jwt;
+
+import javax.enterprise.context.Dependent;
+import javax.enterprise.inject.Produces;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Optional;
+
+@Dependent
+public class JWTAuthContextInfoProvider {
+
+ @Produces
+ Optional<JWTAuthContextInfo> getOptionalContextInfo() {
+ JWTAuthContextInfo contextInfo = new JWTAuthContextInfo();
+
+ // todo use MP Config to load the configuration
+ contextInfo.setIssuedBy("https://server.example.com");
+ RSAPublicKey pk = null;
+ try {
+ pk = (RSAPublicKey) KeyUtils.decodePublicKey("-----BEGIN RSA PUBLIC KEY-----\n" +
+ "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEq\n" +
+ "Fyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwR\n" +
+ "TYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5e\n" +
+ "UF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9\n" +
+ "AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYn\n" +
+ "sIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9x\n" +
+ "nQIDAQAB\n" +
+ "-----END RSA PUBLIC KEY-----\n");
+
+ } catch (final Exception e) {
+ e.printStackTrace();
+ // todo better handling
+ throw new RuntimeException(e);
+ }
+ contextInfo.setSignerKey(pk);
+
+ return Optional.of(contextInfo);
+ }
+
+ @Produces
+ JWTAuthContextInfo getContextInfo() {
+ return getOptionalContextInfo().get();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/830b3729/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipalFactory.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipalFactory.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipalFactory.java
index a64f95a..cb00cc5 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipalFactory.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipalFactory.java
@@ -83,7 +83,7 @@ public abstract class JWTCallerPrincipalFactory {
if (instance == null) {
ServiceLoader<JWTCallerPrincipalFactory> sl = ServiceLoader.load(JWTCallerPrincipalFactory.class, cl);
- URL u = cl.getResource("/META-INF/services/org.eclipse.microprofile.jwt.principal.JWTCallerPrincipalFactory");
+ URL u = cl.getResource("/META-INF/services/org.apache.tomee.microprofile.jwt.JWTCallerPrincipalFactory");
System.out.printf("JWTCallerPrincipalFactory, cl=%s, u=%s, sl=%s\n", cl, u, sl);
try {
for (JWTCallerPrincipalFactory spi : sl) {
http://git-wip-us.apache.org/repos/asf/tomee/blob/830b3729/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JsonValueProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JsonValueProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JsonValueProducer.java
new file mode 100644
index 0000000..355b1d5
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JsonValueProducer.java
@@ -0,0 +1,111 @@
+/*
+ * 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.tomee.microprofile.jwt;
+
+import org.eclipse.microprofile.jwt.Claim;
+import org.eclipse.microprofile.jwt.Claims;
+
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.json.JsonArray;
+import javax.json.JsonNumber;
+import javax.json.JsonObject;
+import javax.json.JsonString;
+import javax.json.JsonValue;
+import java.lang.annotation.Annotation;
+import java.util.Optional;
+import java.util.logging.Logger;
+
+/**
+ * A producer for JsonValue injection types
+ */
+public class JsonValueProducer {
+ private static Logger log = Logger.getLogger(JsonValueProducer.class.getName());
+
+ @Produces
+ @Claim("")
+ public JsonString getJsonString(InjectionPoint ip) {
+ return getValue(ip);
+ }
+
+ @Produces
+ @Claim("")
+ public Optional<JsonString> getOptionalJsonString(InjectionPoint ip) {
+ return getOptionalValue(ip);
+ }
+
+ @Produces
+ @Claim("")
+ public JsonNumber getJsonNumber(InjectionPoint ip) {
+ return getValue(ip);
+ }
+
+ @Produces
+ @Claim("")
+ public Optional<JsonNumber> getOptionalJsonNumber(InjectionPoint ip) {
+ return getOptionalValue(ip);
+ }
+
+ @Produces
+ @Claim("")
+ public JsonArray getJsonArray(InjectionPoint ip) {
+ return getValue(ip);
+ }
+
+ @Produces
+ @Claim("")
+ public Optional<JsonArray> getOptionalJsonArray(InjectionPoint ip) {
+ return getOptionalValue(ip);
+ }
+
+ @Produces
+ @Claim("")
+ public JsonObject getJsonObject(InjectionPoint ip) {
+ return getValue(ip);
+ }
+
+ @Produces
+ @Claim("")
+ public Optional<JsonObject> getOptionalJsonObject(InjectionPoint ip) {
+ return getOptionalValue(ip);
+ }
+
+ public <T extends JsonValue> T getValue(InjectionPoint ip) {
+ log.fine(String.format("JsonValueProducer(%s).produce", ip));
+ String name = getName(ip);
+ T jsonValue = (T) MPJWTProducer.generalJsonValueProducer(name);
+ return jsonValue;
+ }
+
+ public <T extends JsonValue> Optional<T> getOptionalValue(InjectionPoint ip) {
+ log.fine(String.format("JsonValueProducer(%s).produce", ip));
+ String name = getName(ip);
+ T jsonValue = (T) MPJWTProducer.generalJsonValueProducer(name);
+ return Optional.ofNullable(jsonValue);
+ }
+
+ String getName(InjectionPoint ip) {
+ String name = null;
+ for (Annotation ann : ip.getQualifiers()) {
+ if (ann instanceof Claim) {
+ Claim claim = (Claim) ann;
+ name = claim.standard() == Claims.UNKNOWN ? claim.value() : claim.standard().name();
+ }
+ }
+ return name;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/830b3729/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/KeyUtils.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/KeyUtils.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/KeyUtils.java
new file mode 100644
index 0000000..07e00f2
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/KeyUtils.java
@@ -0,0 +1,84 @@
+/*
+ * 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.tomee.microprofile.jwt;
+
+import java.io.InputStream;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Base64;
+
+public class KeyUtils {
+ public static PrivateKey readPrivateKey(String pemResName) throws Exception {
+ InputStream contentIS = KeyUtils.class.getResourceAsStream(pemResName);
+ byte[] tmp = new byte[4096];
+ int length = contentIS.read(tmp);
+ PrivateKey privateKey = decodePrivateKey(new String(tmp, 0, length));
+ return privateKey;
+ }
+
+ public static PublicKey readPublicKey(String pemResName) throws Exception {
+ InputStream contentIS = KeyUtils.class.getResourceAsStream(pemResName);
+ byte[] tmp = new byte[4096];
+ int length = contentIS.read(tmp);
+ PublicKey publicKey = decodePublicKey(new String(tmp, 0, length));
+ return publicKey;
+ }
+
+ public static KeyPair generateKeyPair(int keySize) throws NoSuchAlgorithmException {
+ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
+ keyPairGenerator.initialize(keySize);
+ KeyPair keyPair = keyPairGenerator.genKeyPair();
+ return keyPair;
+ }
+
+ public static PrivateKey decodePrivateKey(String pemEncoded) throws Exception {
+ pemEncoded = removeBeginEnd(pemEncoded);
+ byte[] pkcs8EncodedBytes = Base64.getDecoder().decode(pemEncoded);
+
+ // extract the private key
+
+ PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pkcs8EncodedBytes);
+ KeyFactory kf = KeyFactory.getInstance("RSA");
+ PrivateKey privKey = kf.generatePrivate(keySpec);
+ return privKey;
+ }
+
+ public static PublicKey decodePublicKey(String pemEncoded) throws Exception {
+ pemEncoded = removeBeginEnd(pemEncoded);
+ byte[] encodedBytes = Base64.getDecoder().decode(pemEncoded);
+
+ X509EncodedKeySpec spec = new X509EncodedKeySpec(encodedBytes);
+ KeyFactory kf = KeyFactory.getInstance("RSA");
+ return kf.generatePublic(spec);
+ }
+
+ private static String removeBeginEnd(String pem) {
+ pem = pem.replaceAll("-----BEGIN(.*)KEY-----", "");
+ pem = pem.replaceAll("-----END(.*)KEY-----", "");
+ pem = pem.replaceAll("\r\n", "");
+ pem = pem.replaceAll("\n", "");
+ return pem.trim();
+ }
+ private KeyUtils() {
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/830b3729/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTCDIExtension.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTCDIExtension.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTCDIExtension.java
new file mode 100644
index 0000000..aa15a33
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTCDIExtension.java
@@ -0,0 +1,391 @@
+/*
+ * 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.tomee.microprofile.jwt;
+
+import org.eclipse.microprofile.jwt.Claim;
+import org.eclipse.microprofile.jwt.Claims;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.SessionScoped;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.AfterDeploymentValidation;
+import javax.enterprise.inject.spi.BeanAttributes;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.BeforeBeanDiscovery;
+import javax.enterprise.inject.spi.DeploymentException;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.ProcessBeanAttributes;
+import javax.enterprise.inject.spi.ProcessInjectionPoint;
+import javax.enterprise.inject.spi.ProcessProducer;
+import javax.inject.Provider;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
+import java.util.logging.Logger;
+
+/**
+ * A CDI extension that provides a producer for the current authenticated JsonWebToken based on a thread
+ * local value that is managed by the {@link JWTAuthMechanism} request
+ * authentication handler.
+ * <p>
+ * This also installs the producer methods for the discovered:
+ * <ul>
+ * <li>@Claim ClaimValue<T> injection sites.</li>
+ * <li>@Claim raw type<T> injection sites.</li>
+ * <li>@Claim JsonValue injection sites.</li>
+ * </ul>
+ *
+ * @see JWTAuthMechanism
+ */
+public class MPJWTCDIExtension implements Extension {
+ private static Logger log = Logger.getLogger(MPJWTCDIExtension.class.getName());
+
+ /**
+ * Register the MPJWTProducer JsonWebToken producer bean
+ *
+ * @param bbd before discovery event
+ * @param beanManager cdi bean manager
+ */
+ public void observeBeforeBeanDiscovery(@Observes BeforeBeanDiscovery bbd, BeanManager beanManager) {
+ log.fine(String.format("MPJWTExtension(), added JWTPrincipalProducer"));
+ bbd.addAnnotatedType(beanManager.createAnnotatedType(TCKTokenParser.class));
+ bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTFilter.class));
+ bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTInitializer.class));
+ bbd.addAnnotatedType(beanManager.createAnnotatedType(JWTAuthContextInfoProvider.class));
+ bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTProducer.class));
+ bbd.addAnnotatedType(beanManager.createAnnotatedType(RawClaimTypeProducer.class));
+ bbd.addAnnotatedType(beanManager.createAnnotatedType(ClaimValueProducer.class));
+ bbd.addAnnotatedType(beanManager.createAnnotatedType(JsonValueProducer.class));
+ }
+
+ /**
+ * Replace the general producer method BeanAttributes with one bound to the collected injection site
+ * types to properly reflect all of the type locations the producer method applies to.
+ *
+ * @param pba the ProcessBeanAttributes
+ * @see ClaimProviderBeanAttributes
+ */
+ public void addTypeToClaimProducer(@Observes ProcessBeanAttributes pba) {
+ if (pba.getAnnotated().isAnnotationPresent(Claim.class)) {
+ Claim claim = pba.getAnnotated().getAnnotation(Claim.class);
+ if (claim.value().length() == 0 && claim.standard() == Claims.UNKNOWN) {
+ log.fine(String.format("addTypeToClaimProducer: %s\n", pba.getAnnotated()));
+ BeanAttributes delegate = pba.getBeanAttributes();
+ String name = delegate.getName();
+ if (delegate.getTypes().contains(Optional.class)) {
+ if (providerOptionalTypes.size() == 0) {
+ providerOptionalTypes.add(Optional.class);
+ }
+ pba.setBeanAttributes(new ClaimProviderBeanAttributes(delegate, providerOptionalTypes, providerQualifiers));
+ // This is
+ } else if (name != null && name.startsWith("RawClaimTypeProducer#")) {
+ if (rawTypes.size() == 0) {
+ rawTypes.add(Object.class);
+ }
+ pba.setBeanAttributes(new ClaimProviderBeanAttributes(delegate, rawTypes, rawTypeQualifiers));
+ log.fine(String.format("Setup RawClaimTypeProducer BeanAttributes"));
+ }
+ }
+ }
+ }
+
+ public void afterDeploymentValidation(@Observes AfterDeploymentValidation event, BeanManager beanManager) {
+ }
+
+ void doProcessProducers(@Observes ProcessProducer pp) {
+ }
+
+ /**
+ * Handle the non-{@linkplain Provider}, {@linkplain org.eclipse.microprofile.jwt.ClaimValue}, and
+ * {@linkplain javax.json.JsonValue} claim injection types.
+ *
+ * @param pip - the injection point event information
+ * @see RawClaimTypeProducer
+ */
+ void processClaimInjections(@Observes ProcessInjectionPoint pip) {
+ log.fine(String.format("pipRaw: %s", pip.getInjectionPoint()));
+ InjectionPoint ip = pip.getInjectionPoint();
+ if (ip.getAnnotated().isAnnotationPresent(Claim.class)) {
+ Claim claim = ip.getAnnotated().getAnnotation(Claim.class);
+ if (ip.getType() instanceof Class) {
+ Class rawClass = (Class) ip.getType();
+ // Primative types
+ if (Modifier.isFinal(rawClass.getModifiers())) {
+ rawTypes.add(ip.getType());
+ rawTypeQualifiers.add(claim);
+ log.fine(String.format("+++ Added Claim raw type: %s", ip.getType()));
+ Class declaringClass = ip.getMember().getDeclaringClass();
+ Annotation[] appScoped = declaringClass.getAnnotationsByType(ApplicationScoped.class);
+ Annotation[] sessionScoped = declaringClass.getAnnotationsByType(SessionScoped.class);
+ if ((appScoped != null && appScoped.length > 0) || (sessionScoped != null && sessionScoped.length > 0)) {
+ String err = String.format("A raw type cannot be injected into application/session scope: IP=%s", ip);
+ pip.addDefinitionError(new DeploymentException(err));
+ }
+ }
+ // This handles collections of primative types
+ } else if (isRawParameterizedType(ip.getType())) {
+ log.fine(String.format("+++ Added Claim ParameterizedType: %s", ip.getType()));
+ rawTypes.add(ip.getType());
+ rawTypeQualifiers.add(claim);
+ }
+ } else {
+ log.fine(String.format("Skipping pip: %s, type: %s/%s", ip, ip.getType(), ip.getType().getClass()));
+ }
+ }
+
+ /**
+ * Collect the types of all {@linkplain Provider} injection points annotated with {@linkplain Claim}.
+ *
+ * @param pip - the injection point event information
+ */
+ void processClaimProviderInjections(@Observes ProcessInjectionPoint<?, ? extends Provider> pip) {
+ log.fine(String.format("pip: %s", pip.getInjectionPoint()));
+ final InjectionPoint ip = pip.getInjectionPoint();
+ if (ip.getAnnotated().isAnnotationPresent(Claim.class)) {
+ Claim claim = ip.getAnnotated().getAnnotation(Claim.class);
+ if (claim.value().length() == 0 && claim.standard() == Claims.UNKNOWN) {
+ pip.addDefinitionError(new DeploymentException("@Claim at: " + ip + " has no name or valid standard enum setting"));
+ }
+ boolean usesEnum = claim.standard() != Claims.UNKNOWN;
+ final String claimName = usesEnum ? claim.standard().name() : claim.value();
+ log.fine(String.format("Checking Provider Claim(%s), ip: %s", claimName, ip));
+ ClaimIP claimIP = claims.get(claimName);
+ Type matchType = ip.getType();
+ // The T from the Provider<T> injection site
+ Type actualType = ((ParameterizedType) matchType).getActualTypeArguments()[0];
+ // Don't add Optional or JsonValue as this is handled specially
+ if (!optionalOrJsonValue(actualType)) {
+ rawTypes.add(actualType);
+ } else if (!actualType.getTypeName().startsWith("javax.json.Json")) {
+ // Validate that this is not an Optional<JsonValue>
+ Type innerType = ((ParameterizedType) actualType).getActualTypeArguments()[0];
+ if (!innerType.getTypeName().startsWith("javax.json.Json")) {
+ providerOptionalTypes.add(actualType);
+ providerQualifiers.add(claim);
+ }
+ }
+ rawTypeQualifiers.add(claim);
+ ClaimIPType key = new ClaimIPType(claimName, actualType);
+ if (claimIP == null) {
+ claimIP = new ClaimIP(actualType, actualType, false, claim);
+ claimIP.setProviderSite(true);
+ claims.put(key, claimIP);
+ }
+ claimIP.getInjectionPoints().add(ip);
+ log.fine(String.format("+++ Added Provider Claim(%s) ip: %s", claimName, ip));
+
+ }
+ }
+
+ /**
+ * Create producer methods for each ClaimValue injection site
+ *
+ * @param event - AfterBeanDiscovery
+ * @param beanManager - CDI bean manager
+ */
+ void observesAfterBeanDiscovery(@Observes final AfterBeanDiscovery event, final BeanManager beanManager) {
+ log.fine(String.format("observesAfterBeanDiscovery, %s", claims));
+ installClaimValueProducerMethodsViaSyntheticBeans(event, beanManager);
+
+ //installClaimValueProducesViaTemplateType(event, beanManager);
+ }
+
+ /**
+ * Create a synthetic bean with a custom Producer for the non-Provider injection sites.
+ *
+ * @param event - AfterBeanDiscovery
+ * @param beanManager - CDI bean manager
+ */
+ private void installClaimValueProducerMethodsViaSyntheticBeans(final AfterBeanDiscovery event, final BeanManager beanManager) {
+
+ }
+
+ private boolean optionalOrJsonValue(Type type) {
+ boolean isOptionOrJson = type.getTypeName().startsWith(Optional.class.getTypeName())
+ | type.getTypeName().startsWith("javax.json.Json");
+ return isOptionOrJson;
+ }
+
+ private boolean isRawParameterizedType(Type type) {
+ boolean isRawParameterizedType = false;
+ if (type instanceof ParameterizedType) {
+ ParameterizedType ptype = ParameterizedType.class.cast(type);
+ Type rawType = ptype.getRawType();
+ String rawTypeName = rawType.getTypeName();
+ isRawParameterizedType = !rawTypeName.startsWith("org.eclipse.microprofile.jwt");
+ }
+ return isRawParameterizedType;
+ }
+
+ /**
+ * A map of claim,type pairs to the injection site information
+ */
+ private HashMap<ClaimIPType, ClaimIP> claims = new HashMap<>();
+
+ private Set<Type> providerOptionalTypes = new HashSet<>();
+
+ private Set<Type> providerTypes = new HashSet<>();
+
+ private Set<Type> rawTypes = new HashSet<>();
+
+ private Set<Annotation> rawTypeQualifiers = new HashSet<>();
+
+ private Set<Annotation> providerQualifiers = new HashSet<>();
+
+ /**
+ * A key for a claim,injection site type pair
+ */
+ public static class ClaimIPType implements Comparable<ClaimIPType> {
+ public ClaimIPType(String claimName, Type ipType) {
+ this.claimName = claimName;
+ this.ipType = ipType;
+ }
+
+ /**
+ * Order the @Claim ClaimValue<T> on the @Claim.value and then T type name
+ *
+ * @param o - ClaimIP to compare to
+ * @return the ordering of this claim relative to o
+ */
+ @Override
+ public int compareTo(ClaimIPType o) {
+ int compareTo = claimName.compareTo(o.claimName);
+ if (compareTo == 0) {
+ compareTo = ipType.getTypeName().compareTo(o.ipType.getTypeName());
+ }
+ return compareTo;
+ }
+
+ private String claimName;
+
+ private Type ipType;
+ }
+
+ /**
+ * The representation of an @Claim annotated injection site
+ */
+ public static class ClaimIP {
+ /**
+ * Create a ClaimIP from the injection site information
+ *
+ * @param matchType - the outer type of the injection site
+ * @param valueType - the parameterized type of the injection site
+ * @param isOptional - is the injection site an Optional
+ * @param claim - the Claim qualifier
+ */
+ public ClaimIP(Type matchType, Type valueType, boolean isOptional, Claim claim) {
+ this.matchType = matchType;
+ this.valueType = valueType;
+ this.claim = claim;
+ }
+
+ public Type getMatchType() {
+ return matchType;
+ }
+
+ public String getClaimName() {
+ return claim.standard() == Claims.UNKNOWN ? claim.value() : claim.standard().name();
+ }
+
+ public Claim getClaim() {
+ return claim;
+ }
+
+ public Type getValueType() {
+ return valueType;
+ }
+
+ public boolean isOptional() {
+ return isOptional;
+ }
+
+ public boolean isProviderSite() {
+ return isProviderSite;
+ }
+
+ public void setProviderSite(boolean providerSite) {
+ this.isProviderSite = providerSite;
+ }
+
+ public boolean isNonStandard() {
+ return isNonStandard;
+ }
+
+ public void setNonStandard(boolean nonStandard) {
+ isNonStandard = nonStandard;
+ }
+
+ public boolean isJsonValue() {
+ return isJsonValue;
+ }
+
+ public void setJsonValue(boolean jsonValue) {
+ isJsonValue = jsonValue;
+ }
+
+ public Set<InjectionPoint> getInjectionPoints() {
+ return injectionPoints;
+ }
+
+ @Override
+ public String toString() {
+ return "ClaimIP{" +
+ "type=" + matchType +
+ ", claim=" + claim +
+ ", ips=" + injectionPoints +
+ '}';
+ }
+
+ /**
+ * The injection site value type
+ */
+ private Type matchType;
+
+ /**
+ * The actual type of of the ParameterizedType matchType
+ */
+ private Type valueType;
+
+ /**
+ * Is valueType actually wrapped in an Optional
+ */
+ private boolean isOptional;
+
+ private boolean isProviderSite;
+
+ private boolean isNonStandard;
+
+ private boolean isJsonValue;
+
+ /**
+ * The injection site @Claim annotation value
+ */
+ private Claim claim;
+
+ /**
+ * The location that share the @Claim/type combination
+ */
+ private HashSet<InjectionPoint> injectionPoints = new HashSet<>();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/830b3729/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTContext.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTContext.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTContext.java
index bffccf2..07dfe0b 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTContext.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTContext.java
@@ -27,12 +27,11 @@ import java.util.function.Predicate;
/**
* Responsible for holding the runtime model
*/
-@ApplicationScoped
public class MPJWTContext {
- private final ConcurrentMap<MPJWTConfigKey, MPJWTConfigValue> configuration = new ConcurrentHashMap<>();
+ private static final ConcurrentMap<MPJWTConfigKey, MPJWTConfigValue> configuration = new ConcurrentHashMap<>();
- public MPJWTConfigValue addMapping(final MPJWTConfigKey key, final MPJWTConfigValue value) {
+ public static MPJWTConfigValue addMapping(final MPJWTConfigKey key, final MPJWTConfigValue value) {
Objects.requireNonNull(key, "MP JWT Key is required");
Objects.requireNonNull(value, "MP JWT Value is required");
@@ -44,12 +43,12 @@ public class MPJWTContext {
return value;
}
- public Optional<MPJWTConfigValue> get(final MPJWTConfigKey key) {
+ public static Optional<MPJWTConfigValue> get(final MPJWTConfigKey key) {
Objects.requireNonNull(key, "MP JWT Key is required to retrieve the configuration");
return Optional.ofNullable(configuration.get(key));
}
- public Optional<Map.Entry<MPJWTConfigKey, MPJWTConfigValue>> findFirst(final String path) {
+ public static Optional<Map.Entry<MPJWTConfigKey, MPJWTConfigValue>> findFirst(final String path) {
return configuration.entrySet()
.stream()
.filter(new Predicate<ConcurrentMap.Entry<MPJWTConfigKey, MPJWTConfigValue>>() {
http://git-wip-us.apache.org/repos/asf/tomee/blob/830b3729/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
index 092ad9d..a8f7cb4 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
@@ -38,9 +38,6 @@ import java.util.Optional;
public class MPJWTFilter implements Filter {
@Inject
- private MPJWTContext context;
-
- @Inject
private JWTAuthContextInfo authContextInfo;
@Override
@@ -54,16 +51,31 @@ public class MPJWTFilter implements Filter {
final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
final Optional<Map.Entry<MPJWTContext.MPJWTConfigKey, MPJWTContext.MPJWTConfigValue>> first =
- context.findFirst(httpServletRequest.getRequestURI());
+ MPJWTContext.findFirst(httpServletRequest.getRequestURI());
- if (first.isPresent()) { // nothing found in the context
+ if (!first.isPresent()) { // nothing found in the context
chain.doFilter(request, response);
+ return;
}
// todo get JWT and do validation
// todo not sure what to do with the realm
- final JsonWebToken jsonWebToken = null; // will be build during validation
+ final String authorizationHeader = ((HttpServletRequest) request).getHeader("Authorization");
+ final String token = authorizationHeader.substring("bearer ".length());
+ final JsonWebToken jsonWebToken;
+ try {
+ jsonWebToken = DefaultJWTCallerPrincipalFactory.instance().parse(token, authContextInfo);
+
+ } catch (final ParseException e) {
+ // todo properly handle the exception as required per spec
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+
+ // associate with the producer. Should not be needed.
+ // todo We should be able to retrieve it based on the HTTP Servlet Request in the producer
+ MPJWTProducer.setJWTPrincipal(jsonWebToken);
// now wrap the httpServletRequest and override the principal so CXF can propagate into the SecurityContext
chain.doFilter(new HttpServletRequestWrapper(httpServletRequest) {
@@ -85,6 +97,7 @@ public class MPJWTFilter implements Filter {
}, response);
+
}
@Override
http://git-wip-us.apache.org/repos/asf/tomee/blob/830b3729/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
index dc3d7ba..bb8bb16 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
@@ -34,9 +34,6 @@ import java.util.Set;
@HandlesTypes(LoginConfig.class)
public class MPJWTInitializer implements ServletContainerInitializer {
- @Inject
- private MPJWTContext context;
-
@Override
public void onStartup(final Set<Class<?>> classes, final ServletContext ctx) throws ServletException {
@@ -59,11 +56,13 @@ public class MPJWTInitializer implements ServletContainerInitializer {
final FilterRegistration.Dynamic mpJwtFilter = ctx.addFilter("mp-jwt-filter", MPJWTFilter.class);
mpJwtFilter.setAsyncSupported(true);
+ mpJwtFilter.addMappingForUrlPatterns(null, false, "/*");
- context.addMapping(
+ MPJWTContext.addMapping(
new MPJWTContext.MPJWTConfigKey(
ctx.getContextPath(),
applicationPath == null ? "" : applicationPath.value()),
+
new MPJWTContext.MPJWTConfigValue(
loginConfig.authMethod(),
loginConfig.realmName())
http://git-wip-us.apache.org/repos/asf/tomee/blob/830b3729/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTProducer.java
new file mode 100644
index 0000000..195f323
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTProducer.java
@@ -0,0 +1,196 @@
+/*
+ * 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.tomee.microprofile.jwt;
+
+import org.eclipse.microprofile.jwt.ClaimValue;
+import org.eclipse.microprofile.jwt.JsonWebToken;
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.Destroyed;
+import javax.enterprise.context.Initialized;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Produces;
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+import javax.json.JsonValue;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.logging.Logger;
+
+/**
+ * A class that tracks the current validated MP-JWT and associated JsonWebToken via a thread
+ * local to provide a @RequestScoped JsonWebToken producer method.
+ * <p>
+ * It also provides utility methods for access the current JsonWebToken claim values.
+ */
+@ApplicationScoped
+public class MPJWTProducer {
+ private static Logger log = Logger.getLogger(MPJWTProducer.class.getName());
+ private static final String TMP = "tmp";
+ private static ThreadLocal<JsonWebToken> currentPrincipal = new ThreadLocal<>();
+
+ public static void setJWTPrincipal(JsonWebToken principal) {
+ currentPrincipal.set(principal);
+ }
+
+ public static JsonWebToken getJWTPrincpal() {
+ return currentPrincipal.get();
+ }
+
+ @PostConstruct
+ void init() {
+ log.fine("MPJWTProducer initialized");
+ }
+
+ void observeRequestInitialized(@Observes @Initialized(RequestScoped.class) Object event) {
+ log.finest(String.format("observeRequestInitialized, event=%s", event));
+ }
+
+ void observeRequestDestroyed(@Observes @Destroyed(RequestScoped.class) Object event) {
+ log.finest(String.format("observeRequestDestroyed, event=%s", event));
+ }
+
+ /**
+ * The @RequestScoped producer method for the current JsonWebToken
+ *
+ * @return
+ */
+ @Produces
+ @RequestScoped
+ JsonWebToken currentPrincipalOrNull() {
+ return currentPrincipal.get();
+ }
+
+ /**
+ * A utility method for accessing a claim from the current JsonWebToken as a ClaimValue<Optional<T>> object.
+ *
+ * @param name - name of the claim
+ * @param <T> expected actual type of the claim
+ * @return the claim value wrapper object
+ */
+ static <T> ClaimValue<Optional<T>> generalClaimValueProducer(String name) {
+ ClaimValueWrapper<Optional<T>> wrapper = new ClaimValueWrapper<>(name);
+ T value = getValue(name, false);
+ Optional<T> optValue = Optional.ofNullable(value);
+ wrapper.setValue(optValue);
+ return wrapper;
+ }
+
+ /**
+ * Return the indicated claim value as a JsonValue
+ *
+ * @param name - name of the claim
+ * @return a JsonValue wrapper
+ */
+ static JsonValue generalJsonValueProducer(String name) {
+ Object value = getValue(name, false);
+ JsonValue jsonValue = wrapValue(value);
+ return jsonValue;
+ }
+
+ public static <T> T getValue(String name, boolean isOptional) {
+ JsonWebToken jwt = getJWTPrincpal();
+ if (jwt == null) {
+ log.fine(String.format("getValue(%s), null JsonWebToken", name));
+ return null;
+ }
+
+ Optional<T> claimValue = jwt.claim(name);
+ if (!isOptional && !claimValue.isPresent()) {
+ log.fine(String.format("Failed to find Claim for: %s", name));
+ }
+ log.fine(String.format("getValue(%s), isOptional=%s, claimValue=%s", name, isOptional, claimValue));
+ return claimValue.orElse(null);
+ }
+
+ static JsonObject replaceMap(Map<String, Object> map) {
+ JsonObjectBuilder builder = Json.createObjectBuilder();
+ for (Map.Entry<String, Object> entry : map.entrySet()) {
+ Object entryValue = entry.getValue();
+ if (entryValue instanceof Map) {
+ JsonObject entryJsonObject = replaceMap((Map<String, Object>) entryValue);
+ builder.add(entry.getKey(), entryJsonObject);
+ } else if (entryValue instanceof List) {
+ JsonArray array = (JsonArray) wrapValue(entryValue);
+ builder.add(entry.getKey(), array);
+ } else if (entryValue instanceof Long || entryValue instanceof Integer) {
+ long lvalue = ((Number) entryValue).longValue();
+ builder.add(entry.getKey(), lvalue);
+ } else if (entryValue instanceof Double || entryValue instanceof Float) {
+ double dvalue = ((Number) entryValue).doubleValue();
+ builder.add(entry.getKey(), dvalue);
+ } else if (entryValue instanceof Boolean) {
+ boolean flag = ((Boolean) entryValue).booleanValue();
+ builder.add(entry.getKey(), flag);
+ } else if (entryValue instanceof String) {
+ builder.add(entry.getKey(), entryValue.toString());
+ }
+ }
+ return builder.build();
+ }
+
+ static JsonValue wrapValue(Object value) {
+ JsonValue jsonValue = null;
+ if (value instanceof JsonValue) {
+ // This may already be a JsonValue
+ jsonValue = (JsonValue) value;
+ } else if (value instanceof String) {
+ jsonValue = Json.createObjectBuilder()
+ .add(TMP, value.toString())
+ .build()
+ .getJsonString(TMP);
+ } else if (value instanceof Number) {
+ Number number = (Number) value;
+ if ((number instanceof Long) || (number instanceof Integer)) {
+ jsonValue = Json.createObjectBuilder()
+ .add(TMP, number.longValue())
+ .build()
+ .getJsonNumber(TMP);
+ } else {
+ jsonValue = Json.createObjectBuilder()
+ .add(TMP, number.doubleValue())
+ .build()
+ .getJsonNumber(TMP);
+ }
+ } else if (value instanceof Boolean) {
+ Boolean flag = (Boolean) value;
+ jsonValue = flag ? JsonValue.TRUE : JsonValue.FALSE;
+ } else if (value instanceof Collection) {
+ JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
+ Collection list = (Collection) value;
+ for (Object element : list) {
+ if (element instanceof String) {
+ arrayBuilder.add(element.toString());
+ } else {
+ JsonValue jvalue = wrapValue(element);
+ arrayBuilder.add(jvalue);
+ }
+ }
+ jsonValue = arrayBuilder.build();
+ } else if (value instanceof Map) {
+ jsonValue = replaceMap((Map) value);
+ }
+ return jsonValue;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/830b3729/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/RawClaimTypeProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/RawClaimTypeProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/RawClaimTypeProducer.java
new file mode 100644
index 0000000..b52912c
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/RawClaimTypeProducer.java
@@ -0,0 +1,69 @@
+/*
+ * 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.tomee.microprofile.jwt;
+
+import org.eclipse.microprofile.jwt.Claim;
+import org.eclipse.microprofile.jwt.ClaimValue;
+import org.eclipse.microprofile.jwt.Claims;
+
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.inject.Named;
+import java.lang.annotation.Annotation;
+import java.util.Optional;
+import java.util.logging.Logger;
+
+/**
+ *
+ */
+public class RawClaimTypeProducer {
+ private static Logger log = Logger.getLogger(RawClaimTypeProducer.class.getName());
+
+ @Produces
+ @Claim("")
+ @Named("RawClaimTypeProducer#getValue")
+ public Object getValue(InjectionPoint ip) {
+ log.fine(String.format("getValue(%s)", ip));
+ String name = getName(ip);
+ ClaimValue<Optional<Object>> cv = MPJWTProducer.generalClaimValueProducer(name);
+ Optional<Object> value = cv.getValue();
+ Object returnValue = value.orElse(null);
+ return returnValue;
+ }
+
+ @Produces
+ @Claim("")
+ @Named("RawClaimTypeProducer#getOptionalValue")
+ public Optional getOptionalValue(InjectionPoint ip) {
+ log.fine(String.format("getOptionalValue(%s)", ip));
+ String name = getName(ip);
+ ClaimValue<Optional<Object>> cv = MPJWTProducer.generalClaimValueProducer(name);
+ Optional<Object> value = cv.getValue();
+ return value;
+ }
+
+ String getName(InjectionPoint ip) {
+ String name = null;
+ for (Annotation ann : ip.getQualifiers()) {
+ if (ann instanceof Claim) {
+ Claim claim = (Claim) ann;
+ name = claim.standard() == Claims.UNKNOWN ? claim.value() : claim.standard().name();
+ }
+ }
+ return name;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/830b3729/tck/mp-jwt-embedded/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/tck/mp-jwt-embedded/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
new file mode 100644
index 0000000..5e3bccc
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
@@ -0,0 +1 @@
+org.apache.tomee.microprofile.jwt.MPJWTCDIExtension
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/830b3729/tck/mp-jwt-embedded/src/main/resources/META-INF/services/org.apache.tomee.microprofile.jwt.JWTCallerPrincipalFactory
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/resources/META-INF/services/org.apache.tomee.microprofile.jwt.JWTCallerPrincipalFactory b/tck/mp-jwt-embedded/src/main/resources/META-INF/services/org.apache.tomee.microprofile.jwt.JWTCallerPrincipalFactory
new file mode 100644
index 0000000..67f39db
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/resources/META-INF/services/org.apache.tomee.microprofile.jwt.JWTCallerPrincipalFactory
@@ -0,0 +1 @@
+org.apache.tomee.microprofile.jwt.DefaultJWTCallerPrincipalFactory
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/830b3729/tck/mp-jwt-embedded/src/main/resources/META-INF/services/org.eclipse.microprofile.jwt.principal.JWTCallerPrincipalFactory
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/resources/META-INF/services/org.eclipse.microprofile.jwt.principal.JWTCallerPrincipalFactory b/tck/mp-jwt-embedded/src/main/resources/META-INF/services/org.eclipse.microprofile.jwt.principal.JWTCallerPrincipalFactory
deleted file mode 100644
index 67f39db..0000000
--- a/tck/mp-jwt-embedded/src/main/resources/META-INF/services/org.eclipse.microprofile.jwt.principal.JWTCallerPrincipalFactory
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.tomee.microprofile.jwt.DefaultJWTCallerPrincipalFactory
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/830b3729/tck/mp-jwt-embedded/src/test/java/org/apache/tomee/microprofile/jwt/AppDeploymentExtension.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/test/java/org/apache/tomee/microprofile/jwt/AppDeploymentExtension.java b/tck/mp-jwt-embedded/src/test/java/org/apache/tomee/microprofile/jwt/AppDeploymentExtension.java
new file mode 100644
index 0000000..4ade364
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/test/java/org/apache/tomee/microprofile/jwt/AppDeploymentExtension.java
@@ -0,0 +1,37 @@
+package org.apache.tomee.microprofile.jwt;
+
+import org.jboss.arquillian.container.spi.client.deployment.DeploymentDescription;
+import org.jboss.arquillian.container.test.impl.client.deployment.AnnotationDeploymentScenarioGenerator;
+import org.jboss.arquillian.container.test.spi.client.deployment.DeploymentScenarioGenerator;
+import org.jboss.arquillian.core.spi.LoadableExtension;
+import org.jboss.arquillian.test.spi.TestClass;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+
+import java.util.Collections;
+import java.util.List;
+
+public class AppDeploymentExtension implements LoadableExtension {
+ @Override
+ public void register(final ExtensionBuilder extensionBuilder) {
+ extensionBuilder.service(DeploymentScenarioGenerator.class, SimpleDeploymentScenarioGenerator.class);
+ }
+
+ public static class SimpleDeploymentScenarioGenerator implements DeploymentScenarioGenerator {
+
+ private final DeploymentScenarioGenerator standard = new AnnotationDeploymentScenarioGenerator();
+
+ @Override
+ public List<DeploymentDescription> generate(final TestClass testClass) {
+ final List<DeploymentDescription> stdDeploymentDescriptions = standard.generate(testClass);
+
+ if (stdDeploymentDescriptions != null && !stdDeploymentDescriptions.isEmpty()) {
+ return stdDeploymentDescriptions;
+ }
+
+ return Collections.singletonList(new DeploymentDescription("test.war",
+ ShrinkWrap.create(WebArchive.class, "test.war").add(EmptyAsset.INSTANCE, "WEB-INF/beans.xml")));
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/830b3729/tck/mp-jwt-embedded/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension b/tck/mp-jwt-embedded/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
new file mode 100644
index 0000000..98a4867
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
@@ -0,0 +1 @@
+org.apache.tomee.microprofile.jwt.AppDeploymentExtension
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/830b3729/tck/mp-jwt-embedded/src/test/resources/dev.xml
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/test/resources/dev.xml b/tck/mp-jwt-embedded/src/test/resources/dev.xml
index 16038c9..f6c4fbd 100644
--- a/tck/mp-jwt-embedded/src/test/resources/dev.xml
+++ b/tck/mp-jwt-embedded/src/test/resources/dev.xml
@@ -41,8 +41,9 @@
</run>
</groups>
<classes>
+ <!-- OK
+ -->
<class name="org.eclipse.microprofile.jwt.tck.parsing.TokenValidationTest" />
- <!--
<class name="org.eclipse.microprofile.jwt.tck.util.TokenUtilsTest" />
<class name="org.eclipse.microprofile.jwt.tck.parsing.TestTokenClaimTypesTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.UnsecuredPingTest" />
@@ -52,10 +53,11 @@
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.ProviderInjectionTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.RolesAllowedTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.InvalidTokenTest" />
+ <!-- KO
-->
</classes>
</test>
- <!--
+
<test name="extended-tests" verbose="10">
<groups>
<define name="extended-groups">
@@ -79,5 +81,5 @@
<class name="org.eclipse.microprofile.jwt.tck.container.servlet.ServletTest" />
</classes>
</test>
- -->
+
</suite>
[12/38] tomee git commit: Add a bit more in terms of wiring - still
designing and working on it
Posted by jl...@apache.org.
Add a bit more in terms of wiring - still designing and working on it
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/d987d3ae
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/d987d3ae
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/d987d3ae
Branch: refs/heads/master
Commit: d987d3aedf89abf68e2975cd3c2be4274616a2fc
Parents: 672b422
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Thu Feb 22 22:00:27 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Thu Feb 22 22:00:27 2018 +0100
----------------------------------------------------------------------
.../server/cxf/rs/MPJWTSecurityContextTest.java | 183 ++++++++++++++-----
.../tomee/microprofile/jwt/MPJWTContext.java | 134 ++++++++++++++
.../tomee/microprofile/jwt/MPJWTFilter.java | 22 ++-
.../microprofile/jwt/MPJWTInitializer.java | 19 +-
.../src/main/resources/META-INF/beans.xml | 1 +
5 files changed, 305 insertions(+), 54 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/d987d3ae/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
----------------------------------------------------------------------
diff --git a/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
index 62565b4..10a1305 100644
--- a/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
+++ b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
@@ -21,71 +21,81 @@ import org.apache.cxf.endpoint.Server;
import org.apache.cxf.jaxrs.model.ApplicationInfo;
import org.apache.openejb.jee.WebApp;
import org.apache.openejb.junit.ApplicationComposer;
-import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.observer.Observes;
import org.apache.openejb.server.cxf.rs.event.ServerCreated;
import org.apache.openejb.server.rest.InternalApplication;
-import org.apache.openejb.spi.SecurityService;
import org.apache.openejb.testing.Classes;
import org.apache.openejb.testing.Configuration;
import org.apache.openejb.testing.EnableServices;
import org.apache.openejb.testing.Module;
+import org.apache.openejb.testing.RandomPort;
import org.apache.openejb.testng.PropertiesBuilder;
-import org.apache.openejb.util.NetworkUtil;
import org.eclipse.microprofile.auth.LoginConfig;
-import org.junit.BeforeClass;
+import org.eclipse.microprofile.jwt.JsonWebToken;
import org.junit.Test;
import org.junit.runner.RunWith;
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.annotation.WebFilter;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
import javax.ws.rs.client.ClientBuilder;
-import javax.ws.rs.container.ContainerRequestContext;
-import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.SecurityContext;
-import javax.ws.rs.ext.Provider;
import java.io.IOException;
+import java.lang.annotation.Annotation;
import java.security.Principal;
-import java.util.Objects;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
import java.util.Properties;
+import java.util.Set;
+import java.util.function.Predicate;
import static org.junit.Assert.assertEquals;
@EnableServices("jax-rs")
@RunWith(ApplicationComposer.class)
public class MPJWTSecurityContextTest {
-
- private static int port = -1;
-
- @BeforeClass
- public static void beforeClass() {
- port = NetworkUtil.getNextAvailablePort();
- }
+ @RandomPort("http")
+ private int port;
@Configuration
public Properties props() {
return new PropertiesBuilder()
- .p("httpejbd.port", Integer.toString(port))
.p("observer", "new://Service?class-name=" + Observer.class.getName()) // properly packaged and auto registered
.build();
}
@Module
- @Classes(cdi = true, value = {Res.class, RestApplication.class})
+ @Classes(value = {Res.class, RestApplication.class, MPFilter.class, MPContext.class}, cdi = true)
public WebApp war() {
return new WebApp()
.contextRoot("foo");
}
@Test
- public void check() throws IOException {
+ public void check() {
+ // todo: close the client (just to stay clean even in tests and avoid to potentially leak)
assertEquals("true", ClientBuilder.newClient()
.target("http://127.0.0.1:" + port)
- .path("api/foo/sc")
+ .path("foo/api/sc")
.queryParam("role", "therole")
.request()
.accept(MediaType.TEXT_PLAIN_TYPE)
@@ -93,7 +103,7 @@ public class MPJWTSecurityContextTest {
assertEquals("false", ClientBuilder.newClient()
.target("http://127.0.0.1:" + port)
- .path("api/foo/sc")
+ .path("foo/api/sc")
.queryParam("role", "another")
.request()
.accept(MediaType.TEXT_PLAIN_TYPE)
@@ -107,13 +117,12 @@ public class MPJWTSecurityContextTest {
}
@Path("sc")
+ @ApplicationScoped
public static class Res {
- @Context
- private SecurityContext sc;
-
@GET
- public boolean f() {
- return sc.isUserInRole("therole");
+ @Produces(MediaType.TEXT_PLAIN)
+ public boolean f(@Context final SecurityContext ctx, @QueryParam("role") final String role) {
+ return ctx.isUserInRole(role);
}
}
@@ -132,46 +141,120 @@ public class MPJWTSecurityContextTest {
final LoginConfig annotation = application.getClass().getAnnotation(LoginConfig.class);
if (annotation != null && "MP-JWT".equals(annotation.authMethod())) {
// add the ContainerRequestFilter on the fly
- // todo how to add this on the fly
}
}
}
- // this should also be packaged into the same module and delegate to the security service
- @Provider
- public static class MPJWTSecurityContext implements ContainerRequestFilter {
-
- private final SecurityService securityService;
-
- public MPJWTSecurityContext() {
- securityService = SystemInstance.get().getComponent(SecurityService.class);
- Objects.requireNonNull(securityService, "A security context needs to be properly configured to enforce security in REST services");
- }
+ // todo: industrialize that but idea is to fill that during startup to let it be usable at runtime
+ // note: the bean must be added through an extension in a real impl
+ @ApplicationScoped
+ public static class MPContext {
+ // todo: login config model, not the raw annot
+ private Map<String, LoginConfig> configs = new HashMap<>();
- @Override
- public void filter(final ContainerRequestContext containerRequestContext) throws IOException {
- containerRequestContext.setSecurityContext(new SecurityContext() {
- @Override
- public Principal getUserPrincipal() {
- return securityService.getCallerPrincipal();
- }
+ @PostConstruct
+ private void init() {
+ // todo: drop and replace by actual init
+ configs.put("/api", new LoginConfig() {
@Override
- public boolean isUserInRole(final String s) {
- return securityService.isCallerInRole(s);
+ public Class<? extends Annotation> annotationType() {
+ return LoginConfig.class;
}
@Override
- public boolean isSecure() {
- return false;
+ public String authMethod() {
+ return "MP-JWT";
}
@Override
- public String getAuthenticationScheme() {
- return "MP-JWT";
+ public String realmName() {
+ return "";
}
});
}
+
+ public Map<String, LoginConfig> getConfigs() {
+ return configs;
+ }
}
-}
+ @WebFilter(asyncSupported = true, urlPatterns = "/*") // addbefore from an initializer
+ public static class MPFilter implements Filter {
+ @Inject
+ private MPContext context;
+
+ @Override
+ public void init(final FilterConfig filterConfig) throws ServletException {
+ // no-op
+ }
+
+ @Override
+ public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
+ throws IOException, ServletException {
+ final HttpServletRequest httpServletRequest = HttpServletRequest.class.cast(request);
+ final String uri = httpServletRequest.getRequestURI().substring(httpServletRequest.getContextPath().length());
+
+ // todo: better handling of conflicting app paths?
+ final Optional<Map.Entry<String, LoginConfig>> first = context.getConfigs()
+ .entrySet()
+ .stream()
+ .filter(new Predicate<Map.Entry<String, LoginConfig>>() {
+ @Override
+ public boolean test(final Map.Entry<String, LoginConfig> e) {
+ return uri.startsWith(e.getKey());
+ }
+ })
+ .findFirst();
+
+ if (first.isPresent()) {
+ chain.doFilter(new HttpServletRequestWrapper(httpServletRequest) {
+ private final MPPcp pcp = new MPPcp();
+
+ @Override
+ public Principal getUserPrincipal() {
+ return pcp;
+ }
+
+ @Override
+ public boolean isUserInRole(final String role) {
+ return pcp.getGroups().contains(role);
+ }
+ }, response);
+
+ } else {
+ chain.doFilter(request, response);
+
+ }
+ }
+
+ @Override
+ public void destroy() {
+ // no-op
+ }
+ }
+
+ // todo
+ public static class MPPcp implements JsonWebToken {
+
+ @Override
+ public String getName() {
+ return "mp";
+ }
+
+ @Override
+ public Set<String> getClaimNames() {
+ return Collections.singleton("test");
+ }
+
+ @Override
+ public <T> T getClaim(String claimName) {
+ return (T) "foo";
+ }
+
+ @Override
+ public Set<String> getGroups() {
+ return Collections.singleton("therole");
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/d987d3ae/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTContext.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTContext.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTContext.java
new file mode 100644
index 0000000..2197745
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTContext.java
@@ -0,0 +1,134 @@
+/*
+ * 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.tomee.microprofile.jwt;
+
+import org.eclipse.microprofile.auth.LoginConfig;
+
+import javax.enterprise.context.ApplicationScoped;
+import java.net.URI;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.function.Predicate;
+
+/**
+ * Responsible for holding the runtime model
+ */
+@ApplicationScoped
+public class MPJWTContext {
+
+ private final ConcurrentMap<MPJWTConfigKey, MPJWTConfigValue> configuration = new ConcurrentHashMap<>();
+
+ public MPJWTConfigValue addMapping(final MPJWTConfigKey key, final MPJWTConfigValue value) {
+ Objects.requireNonNull(key, "MP JWT Key is required");
+ Objects.requireNonNull(value, "MP JWT Value is required");
+
+ final MPJWTConfigValue oldValue = configuration.putIfAbsent(key, value);
+ if (oldValue != null) {
+ throw new IllegalStateException("A mapping has already been defined for the key " + key);
+ }
+
+ return value;
+ }
+
+ public Optional<MPJWTConfigValue> get(final MPJWTConfigKey key) {
+ Objects.requireNonNull(key, "MP JWT Key is required to retrieve the configuration");
+ return Optional.ofNullable(configuration.get(key));
+ }
+
+ public Optional<Map.Entry<MPJWTConfigKey, MPJWTConfigValue>> findFirst(final String path) {
+ return configuration.entrySet()
+ .stream()
+ .filter(new Predicate<ConcurrentMap.Entry<MPJWTConfigKey, MPJWTConfigValue>>() {
+ @Override
+ public boolean test(final ConcurrentMap.Entry<MPJWTConfigKey, MPJWTConfigValue> e) {
+ return path.startsWith(e.getKey().toURI());
+ }
+ })
+ .findFirst();
+ }
+
+
+ public static class MPJWTConfigValue {
+ private final String authMethod;
+ private final String realm;
+
+ public MPJWTConfigValue(final String authMethod, final String realm) {
+ this.authMethod = authMethod;
+ this.realm = realm;
+ }
+
+ public String getAuthMethod() {
+ return authMethod;
+ }
+
+ public String getRealm() {
+ return realm;
+ }
+ }
+
+ public static class MPJWTConfigKey {
+ private final String contextPath;
+ private final String applicationPath;
+
+ public MPJWTConfigKey(final String contextPath, final String applicationPath) {
+ this.contextPath = contextPath;
+ this.applicationPath = applicationPath;
+ }
+
+ public String getApplicationPath() {
+ return applicationPath;
+ }
+
+ public String getContextPath() {
+ return contextPath;
+ }
+
+ public String toURI() {
+ return ("/" + contextPath + "/" + applicationPath).replaceAll("//", "/");
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ final MPJWTConfigKey that = (MPJWTConfigKey) o;
+
+ if (contextPath != null ? !contextPath.equals(that.contextPath) : that.contextPath != null) return false;
+ return !(applicationPath != null ? !applicationPath.equals(that.applicationPath) : that.applicationPath != null);
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = contextPath != null ? contextPath.hashCode() : 0;
+ result = 31 * result + (applicationPath != null ? applicationPath.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "MPJWTConfigKey{" +
+ "applicationPath='" + applicationPath + '\'' +
+ ", contextPath='" + contextPath + '\'' +
+ '}';
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/d987d3ae/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
index 9b57b51..cb235fa 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
@@ -16,6 +16,9 @@
*/
package org.apache.tomee.microprofile.jwt;
+import org.eclipse.microprofile.jwt.JsonWebToken;
+
+import javax.inject.Inject;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
@@ -27,11 +30,15 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;
import java.security.Principal;
+import java.util.Map;
+import java.util.Optional;
// async is supported because we only need to do work on the way in
@WebFilter(asyncSupported = true, urlPatterns = "/*")
public class MPJWTFilter implements Filter {
+ @Inject
+ private MPJWTContext context;
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
@@ -42,21 +49,30 @@ public class MPJWTFilter implements Filter {
@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
- final HttpServletRequest httpServletRequest = (HttpServletRequest)request;
+ final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
+ final Optional<Map.Entry<MPJWTContext.MPJWTConfigKey, MPJWTContext.MPJWTConfigValue>> first =
+ context.findFirst(httpServletRequest.getRequestURI());
+
+ if (first.isPresent()) { // nothing found in the context
+ chain.doFilter(request, response);
+ }
// todo get JWT and do validation
+ // todo not sure what to do with the realm
+
+ final JsonWebToken jsonWebToken = new DefaultJWTCallerPrincipal("bla"); // will be build during validation
// now wrap the httpServletRequest and override the principal so CXF can propagate into the SecurityContext
chain.doFilter(new HttpServletRequestWrapper(httpServletRequest) {
@Override
public Principal getUserPrincipal() {
- return null; // todo, during parsing and validation, we need to convert into the JWT Principal as specified by the spec
+ return jsonWebToken;
}
@Override
public boolean isUserInRole(String role) {
- return true; // replace with a check based on the claims content
+ return jsonWebToken.getGroups().contains(role);
}
@Override
http://git-wip-us.apache.org/repos/asf/tomee/blob/d987d3ae/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
index e91047d..dc3d7ba 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
@@ -18,11 +18,13 @@ package org.apache.tomee.microprofile.jwt;
import org.eclipse.microprofile.auth.LoginConfig;
+import javax.inject.Inject;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.HandlesTypes;
+import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import java.util.Set;
@@ -32,6 +34,9 @@ import java.util.Set;
@HandlesTypes(LoginConfig.class)
public class MPJWTInitializer implements ServletContainerInitializer {
+ @Inject
+ private MPJWTContext context;
+
@Override
public void onStartup(final Set<Class<?>> classes, final ServletContext ctx) throws ServletException {
@@ -46,12 +51,24 @@ public class MPJWTInitializer implements ServletContainerInitializer {
continue;
}
- if (!Application.class.isInstance(clazz)) {
+ if (!Application.class.isAssignableFrom(clazz)) {
continue; // do we really want Application?
}
+ final ApplicationPath applicationPath = clazz.getAnnotation(ApplicationPath.class);
+
final FilterRegistration.Dynamic mpJwtFilter = ctx.addFilter("mp-jwt-filter", MPJWTFilter.class);
mpJwtFilter.setAsyncSupported(true);
+
+ context.addMapping(
+ new MPJWTContext.MPJWTConfigKey(
+ ctx.getContextPath(),
+ applicationPath == null ? "" : applicationPath.value()),
+ new MPJWTContext.MPJWTConfigValue(
+ loginConfig.authMethod(),
+ loginConfig.realmName())
+ );
+
}
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/d987d3ae/tck/mp-jwt-embedded/src/main/resources/META-INF/beans.xml
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/resources/META-INF/beans.xml b/tck/mp-jwt-embedded/src/main/resources/META-INF/beans.xml
new file mode 100644
index 0000000..330c7f6
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/resources/META-INF/beans.xml
@@ -0,0 +1 @@
+<beans/>
\ No newline at end of file
[30/38] tomee git commit: Revert changes on
ExtensionProviderRegistration
Posted by jl...@apache.org.
Revert changes on ExtensionProviderRegistration
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/ae7c21ea
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/ae7c21ea
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/ae7c21ea
Branch: refs/heads/master
Commit: ae7c21ea514594031cad102ad871203ef1f6bcb0
Parents: e75018b
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Wed Mar 7 08:12:10 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Wed Mar 7 08:12:10 2018 +0100
----------------------------------------------------------------------
.../apache/openejb/server/cxf/rs/CxfRsHttpListener.java | 2 +-
.../cxf/rs/event/ExtensionProviderRegistration.java | 9 +--------
.../microprofile/jwt/jaxrs/MPJWPProviderRegistration.java | 10 ----------
3 files changed, 2 insertions(+), 19 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/ae7c21ea/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java
----------------------------------------------------------------------
diff --git a/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java
index 305a1c1..e10172f 100644
--- a/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java
+++ b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java
@@ -1019,7 +1019,7 @@ public class CxfRsHttpListener implements RsHttpListener {
}
}
- SystemInstance.get().fireEvent(new ExtensionProviderRegistration(server,
+ SystemInstance.get().fireEvent(new ExtensionProviderRegistration(
AppFinder.findAppContextOrWeb(Thread.currentThread().getContextClassLoader(), AppFinder.AppContextTransformer.INSTANCE), providers));
if (!providers.isEmpty()) {
http://git-wip-us.apache.org/repos/asf/tomee/blob/ae7c21ea/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/event/ExtensionProviderRegistration.java
----------------------------------------------------------------------
diff --git a/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/event/ExtensionProviderRegistration.java b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/event/ExtensionProviderRegistration.java
index 7af089f..cfae25c 100644
--- a/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/event/ExtensionProviderRegistration.java
+++ b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/event/ExtensionProviderRegistration.java
@@ -16,7 +16,6 @@
*/
package org.apache.openejb.server.cxf.rs.event;
-import org.apache.cxf.endpoint.Server;
import org.apache.openejb.AppContext;
import org.apache.openejb.observer.Event;
@@ -26,12 +25,10 @@ import java.util.List;
// this event can allow to add/remove/resort providers
@Event
public class ExtensionProviderRegistration {
- private final Server server;
private final List<Object> providers;
private final AppContext appContext;
- public ExtensionProviderRegistration(final Server server, final AppContext ctx, final List<Object> existings) {
- this.server = server;
+ public ExtensionProviderRegistration(final AppContext ctx, final List<Object> existings) {
this.appContext = ctx;
this.providers = existings;
}
@@ -44,10 +41,6 @@ public class ExtensionProviderRegistration {
return providers;
}
- public Server getServer() {
- return server;
- }
-
@Override
public String toString() {
return "ExtensionProviderRegistration{}";
http://git-wip-us.apache.org/repos/asf/tomee/blob/ae7c21ea/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWPProviderRegistration.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWPProviderRegistration.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWPProviderRegistration.java
index 29c146e..2102c89 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWPProviderRegistration.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWPProviderRegistration.java
@@ -19,16 +19,6 @@ package org.apache.tomee.microprofile.jwt.jaxrs;
import org.apache.openejb.observer.Observes;
import org.apache.openejb.server.cxf.rs.event.ExtensionProviderRegistration;
import org.apache.tomee.microprofile.jwt.MPJWTFilter;
-import org.eclipse.microprofile.auth.LoginConfig;
-
-import javax.servlet.FilterRegistration;
-import javax.servlet.ServletContainerInitializer;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.annotation.HandlesTypes;
-import javax.ws.rs.ApplicationPath;
-import javax.ws.rs.core.Application;
-import java.util.Set;
/**
* OpenEJB/TomEE hack to register a new provider on the fly
[26/38] tomee git commit: Provider and Instance
Posted by jl...@apache.org.
Provider and Instance
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/cfc2ae1f
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/cfc2ae1f
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/cfc2ae1f
Branch: refs/heads/master
Commit: cfc2ae1f873a5b413cd79af69969f4dfe620829d
Parents: b05e564
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Fri Mar 2 15:40:17 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Fri Mar 2 15:40:17 2018 +0100
----------------------------------------------------------------------
.../org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java | 2 ++
.../tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java | 9 +++++++++
tck/mp-jwt-embedded/src/test/resources/dev.xml | 8 ++++----
3 files changed, 15 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/cfc2ae1f/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
index 0e87404..0b6f3de 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
@@ -168,11 +168,13 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
// handle Provider<T>
if (rawTypeClass.isAssignableFrom(Provider.class)) {
+ final Type providerType = paramType.getActualTypeArguments()[0];
return getClaimValue(key);
}
// handle Instance<T>
if (rawTypeClass.isAssignableFrom(Instance.class)) {
+ final Type instanceType = paramType.getActualTypeArguments()[0];
return getClaimValue(key);
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/cfc2ae1f/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
index 9f8e602..05b08de 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
@@ -23,6 +23,7 @@ import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfoProvider;
import org.eclipse.microprofile.jwt.Claim;
import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Instance;
import javax.enterprise.inject.spi.AfterBeanDiscovery;
import javax.enterprise.inject.spi.AfterDeploymentValidation;
import javax.enterprise.inject.spi.BeanManager;
@@ -46,6 +47,7 @@ public class MPJWTCDIExtension implements Extension {
private static Logger logger = Logger.getLogger(MPJWTCDIExtension.class.getName());
private static final Predicate<InjectionPoint> NOT_PROVIDERS = ip -> (ip.getType() instanceof Class) || (ip.getType() instanceof ParameterizedType && ((ParameterizedType)ip.getType()).getRawType() != Provider.class);
+ private static final Predicate<InjectionPoint> NOT_INSTANCES = ip -> (ip.getType() instanceof Class) || (ip.getType() instanceof ParameterizedType && ((ParameterizedType)ip.getType()).getRawType() != Instance.class);
private static final Map<Type, Type> REPLACED_TYPES = new HashMap<>();
static {
@@ -68,6 +70,7 @@ public class MPJWTCDIExtension implements Extension {
public void registerClaimProducer(@Observes final AfterBeanDiscovery abd, final BeanManager bm) {
final Set<Type> types = injectionPoints.stream()
.filter(NOT_PROVIDERS)
+ .filter(NOT_INSTANCES)
.map(ip -> REPLACED_TYPES.getOrDefault(ip.getType(), ip.getType()))
.collect(Collectors.toSet());
@@ -76,7 +79,13 @@ public class MPJWTCDIExtension implements Extension {
.map(ip -> ((ParameterizedType)ip.getType()).getActualTypeArguments()[0])
.collect(Collectors.toSet());
+ final Set<Type> instanceTypes = injectionPoints.stream()
+ .filter(NOT_INSTANCES.negate())
+ .map(ip -> ((ParameterizedType)ip.getType()).getActualTypeArguments()[0])
+ .collect(Collectors.toSet());
+
types.addAll(providerTypes);
+ types.addAll(instanceTypes);
types.stream()
.map(type -> new ClaimBean<>(bm, type))
http://git-wip-us.apache.org/repos/asf/tomee/blob/cfc2ae1f/tck/mp-jwt-embedded/src/test/resources/dev.xml
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/test/resources/dev.xml b/tck/mp-jwt-embedded/src/test/resources/dev.xml
index 27205d2..b10e250 100644
--- a/tck/mp-jwt-embedded/src/test/resources/dev.xml
+++ b/tck/mp-jwt-embedded/src/test/resources/dev.xml
@@ -42,7 +42,6 @@
</groups>
<classes>
<!-- OK
- -->
<class name="org.eclipse.microprofile.jwt.tck.parsing.TokenValidationTest" />
<class name="org.eclipse.microprofile.jwt.tck.util.TokenUtilsTest" />
<class name="org.eclipse.microprofile.jwt.tck.parsing.TestTokenClaimTypesTest" />
@@ -53,13 +52,14 @@
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.JsonValueInjectionTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.RolesAllowedTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.InvalidTokenTest" />
- <!-- KO
+ -->
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.ProviderInjectionTest" />
+ <!-- KO
-->
</classes>
</test>
-
+ <!--
<test name="extended-tests" verbose="10">
<groups>
<define name="extended-groups">
@@ -83,5 +83,5 @@
<class name="org.eclipse.microprofile.jwt.tck.container.jacc.SubjectTest" />
</classes>
</test>
-
+ -->
</suite>
[23/38] tomee git commit: Iterate
Posted by jl...@apache.org.
Iterate
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/50608069
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/50608069
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/50608069
Branch: refs/heads/master
Commit: 506080699d96c06db707ba66a4342aabf5e378f3
Parents: d81bd39
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Fri Mar 2 09:14:46 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Fri Mar 2 09:14:46 2018 +0100
----------------------------------------------------------------------
.../tomee/microprofile/jwt/cdi/ClaimBean.java | 32 +++++++++++++++++---
.../microprofile/jwt/cdi/MPJWTCDIExtension.java | 2 +-
2 files changed, 28 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/50608069/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
index d04d807..ad713dd 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
@@ -17,7 +17,9 @@
package org.apache.tomee.microprofile.jwt.cdi;
import org.eclipse.microprofile.jwt.Claim;
+import org.eclipse.microprofile.jwt.ClaimValue;
import org.eclipse.microprofile.jwt.Claims;
+import org.eclipse.microprofile.jwt.JsonWebToken;
import javax.enterprise.context.Dependent;
import javax.enterprise.context.spi.CreationalContext;
@@ -35,9 +37,12 @@ import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
+import java.util.logging.Logger;
public class ClaimBean<T> implements Bean<T>, PassivationCapable {
+ private static Logger logger = Logger.getLogger(MPJWTCDIExtension.class.getName());
+
private final static Set<Annotation> QUALIFIERS = new HashSet<>();
private final BeanManager bm;
@@ -53,7 +58,7 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
this.id = "ClaimBean_" + types;
}
- private Class getRawType(Type type) {
+ private Class getRawType(final Type type) {
if (type instanceof Class) {
return (Class) type;
@@ -63,7 +68,7 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
return (Class) paramType.getRawType();
}
- // todo deal with Optional here?
+ // todo deal with Optional here? aka check type again
throw new UnsupportedOperationException("Unsupported type " + type);
}
@@ -132,9 +137,12 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
}
final Annotated annotated = ip.getAnnotated();
- Claim claim = annotated.getAnnotation(Claim.class);
+ final Claim claim = annotated.getAnnotation(Claim.class);
final String key = getClaimKey(claim);
+ System.out.println(String.format("Found Claim injection with name=%s and for InjectionPoint=%s", key, ip.toString()));
+ logger.finest(String.format("Found Claim injection with name=%s and for InjectionPoint=%s", key, ip.toString()));
+
if (annotated.getBaseType() instanceof ParameterizedType) {
final ParameterizedType paramType = (ParameterizedType) annotated.getBaseType();
final Type rawType = paramType.getRawType();
@@ -148,6 +156,12 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
return (T) getClaimValue(key, clazz);
}
+ // handle ClaimValue<T>
+ if (rawTypeClass.isAssignableFrom(ClaimValue.class)) {
+ final Class clazz = (Class) paramType.getActualTypeArguments()[0]; //X TODO check type again, etc
+ return (T) getClaimValue(key, clazz);
+ }
+
// handle Optional<T>
if (rawTypeClass.isAssignableFrom(Optional.class)) {
final Class clazz = (Class) paramType.getActualTypeArguments()[0]; //X TODO check type again, etc
@@ -180,8 +194,16 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
return claim.standard() == Claims.UNKNOWN ? claim.value() : claim.standard().name();
}
- private T getClaimValue(final String key, final Class clazz) {
- return null; // todo
+ private T getClaimValue(final String name, final Class clazz) {
+ final JsonWebToken jwt = MPJWTProducer.getJWTPrincpal();
+ if (jwt == null) {
+ logger.warning(String.format("Can't retrieve claim %s. No active principal.", name));
+ return null;
+ }
+
+ final Optional<T> claimValue = jwt.claim(name);
+ logger.finest(String.format("Found ClaimValue=%s for name=%s", claimValue, name));
+ return claimValue.orElse(null); // todo more to do?
}
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/50608069/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
index 88981d4..9f8e602 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
@@ -65,7 +65,7 @@ public class MPJWTCDIExtension implements Extension {
}
}
- public void registerConfigProducer(@Observes final AfterBeanDiscovery abd, final BeanManager bm) {
+ public void registerClaimProducer(@Observes final AfterBeanDiscovery abd, final BeanManager bm) {
final Set<Type> types = injectionPoints.stream()
.filter(NOT_PROVIDERS)
.map(ip -> REPLACED_TYPES.getOrDefault(ip.getType(), ip.getType()))
[18/38] tomee git commit: some refactoring
Posted by jl...@apache.org.
some refactoring
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/c5964e07
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/c5964e07
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/c5964e07
Branch: refs/heads/master
Commit: c5964e079df2dbadc0bd5f7f6567aaf509c69d83
Parents: 830b372
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Tue Feb 27 10:14:53 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Tue Feb 27 10:14:53 2018 +0100
----------------------------------------------------------------------
.../tomee/microprofile/jwt/ClaimLiteral.java | 32 --
.../jwt/ClaimProviderBeanAttributes.java | 83 ----
.../microprofile/jwt/ClaimValueProducer.java | 75 ----
.../microprofile/jwt/ClaimValueWrapper.java | 54 ---
.../jwt/DefaultJWTCallerPrincipal.java | 334 ----------------
.../jwt/DefaultJWTCallerPrincipalFactory.java | 86 ----
.../microprofile/jwt/JWTAuthContextInfo.java | 66 ----
.../jwt/JWTAuthContextInfoProvider.java | 59 ---
.../microprofile/jwt/JWTCallerPrincipal.java | 59 ---
.../jwt/JWTCallerPrincipalFactory.java | 124 ------
.../microprofile/jwt/JsonValueProducer.java | 111 ------
.../microprofile/jwt/MPJWTCDIExtension.java | 391 ------------------
.../tomee/microprofile/jwt/MPJWTFilter.java | 4 +
.../tomee/microprofile/jwt/MPJWTProducer.java | 196 ---------
.../microprofile/jwt/RawClaimTypeProducer.java | 69 ----
.../tomee/microprofile/jwt/TCKTokenParser.java | 3 +
.../microprofile/jwt/cdi/ClaimLiteral.java | 32 ++
.../jwt/cdi/ClaimProviderBeanAttributes.java | 83 ++++
.../jwt/cdi/ClaimValueProducer.java | 75 ++++
.../microprofile/jwt/cdi/ClaimValueWrapper.java | 54 +++
.../microprofile/jwt/cdi/JsonValueProducer.java | 111 ++++++
.../microprofile/jwt/cdi/MPJWTCDIExtension.java | 395 +++++++++++++++++++
.../microprofile/jwt/cdi/MPJWTProducer.java | 196 +++++++++
.../jwt/cdi/RawClaimTypeProducer.java | 69 ++++
.../jwt/config/JWTAuthContextInfo.java | 66 ++++
.../jwt/config/JWTAuthContextInfoProvider.java | 61 +++
.../principal/DefaultJWTCallerPrincipal.java | 334 ++++++++++++++++
.../DefaultJWTCallerPrincipalFactory.java | 88 +++++
.../jwt/principal/JWTCallerPrincipal.java | 59 +++
.../principal/JWTCallerPrincipalFactory.java | 127 ++++++
.../javax.enterprise.inject.spi.Extension | 2 +-
...e.microprofile.jwt.JWTCallerPrincipalFactory | 1 -
...file.jwt.principal.JWTCallerPrincipalFactory | 1 +
33 files changed, 1759 insertions(+), 1741 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimLiteral.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimLiteral.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimLiteral.java
deleted file mode 100644
index 5471b2e..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimLiteral.java
+++ /dev/null
@@ -1,32 +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.tomee.microprofile.jwt;
-
-import javax.enterprise.util.AnnotationLiteral;
-
-import org.eclipse.microprofile.jwt.Claim;
-import org.eclipse.microprofile.jwt.Claims;
-
-public class ClaimLiteral extends AnnotationLiteral<Claim> implements Claim {
- public String value() {
- return "";
- }
-
- public Claims standard() {
- return Claims.UNKNOWN;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimProviderBeanAttributes.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimProviderBeanAttributes.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimProviderBeanAttributes.java
deleted file mode 100644
index ce6e97c..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimProviderBeanAttributes.java
+++ /dev/null
@@ -1,83 +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.tomee.microprofile.jwt;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import java.util.Set;
-
-import javax.enterprise.inject.spi.BeanAttributes;
-
-/**
- * An implementation of BeanAttributes<Object> that wraps the generic producer BeanAttributes
- * to allow the MPJWTExtension to collect the types of all corresponding injection sites
- *
- */
-public class ClaimProviderBeanAttributes implements BeanAttributes<Object> {
- /**
- * Decorate the ConfigPropertyProducer BeanAttributes to set the types the producer applies to. This set is collected
- * from all injection points annotated with @ConfigProperty.
- *
- * @param delegate - the original producer method BeanAttributes
- * @param types - the full set of @Claim injection point types
- */
- public ClaimProviderBeanAttributes(BeanAttributes<Object> delegate, Set<Type> types, Set<Annotation> qualifiers) {
- this.delegate = delegate;
- this.types = types;
- this.qualifiers = qualifiers;
- if (types.size() == 0) {
- Thread.dumpStack();
- }
- }
-
- @Override
- public Set<Type> getTypes() {
- return types;
- }
-
- @Override
- public Set<Annotation> getQualifiers() {
- return qualifiers;
- }
-
- @Override
- public Class<? extends Annotation> getScope() {
- return delegate.getScope();
- }
-
- @Override
- public String getName() {
- return delegate.getName();
- }
-
- @Override
- public Set<Class<? extends Annotation>> getStereotypes() {
- return delegate.getStereotypes();
- }
-
- @Override
- public boolean isAlternative() {
- return delegate.isAlternative();
- }
-
- private BeanAttributes<Object> delegate;
-
- private Set<Type> types;
-
- private Set<Annotation> qualifiers;
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimValueProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimValueProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimValueProducer.java
deleted file mode 100644
index ae2338f..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimValueProducer.java
+++ /dev/null
@@ -1,75 +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.tomee.microprofile.jwt;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.Optional;
-
-import javax.enterprise.inject.Produces;
-import javax.enterprise.inject.spi.InjectionPoint;
-
-import org.eclipse.microprofile.jwt.Claim;
-import org.eclipse.microprofile.jwt.ClaimValue;
-import org.eclipse.microprofile.jwt.Claims;
-
-/**
- * A producer for the ClaimValue<T> wrapper injection sites.
- * @param <T> the raw claim type
- */
-public class ClaimValueProducer<T> {
-
- @Produces
- @Claim("")
- ClaimValue<T> produce(InjectionPoint ip) {
- String name = getName(ip);
- ClaimValue<Optional<T>> cv = MPJWTProducer.generalClaimValueProducer(name);
- ClaimValue<T> returnValue = (ClaimValue<T>) cv;
- Optional<T> value = cv.getValue();
- // Pull out the ClaimValue<T> T type,
- Type matchType = ip.getType();
- Type actualType = Object.class;
- boolean isOptional = false;
- if (matchType instanceof ParameterizedType) {
- actualType = ((ParameterizedType) matchType).getActualTypeArguments()[0];
- isOptional = matchType.getTypeName().equals(Optional.class.getTypeName());
- if (isOptional) {
- actualType = ((ParameterizedType) matchType).getActualTypeArguments()[0];
- }
- }
-
- if (!actualType.getTypeName().startsWith(Optional.class.getTypeName())) {
- T nestedValue = value.orElse(null);
- ClaimValueWrapper<T> wrapper = new ClaimValueWrapper<>(cv.getName());
- wrapper.setValue(nestedValue);
- returnValue = wrapper;
- }
- return returnValue;
- }
-
- String getName(InjectionPoint ip) {
- String name = null;
- for (Annotation ann : ip.getQualifiers()) {
- if (ann instanceof Claim) {
- Claim claim = (Claim) ann;
- name = claim.standard() == Claims.UNKNOWN ? claim.value() : claim.standard().name();
- }
- }
- return name;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimValueWrapper.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimValueWrapper.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimValueWrapper.java
deleted file mode 100644
index cc16771..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ClaimValueWrapper.java
+++ /dev/null
@@ -1,54 +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.tomee.microprofile.jwt;
-
-import org.eclipse.microprofile.jwt.ClaimValue;
-
-/**
- * An implementation of the ClaimValue interface
- *
- * @param <T> the claim value type
- */
-public class ClaimValueWrapper<T> implements ClaimValue<T> {
- private String name;
-
- private T value;
-
- public ClaimValueWrapper(String name) {
- this.name = name;
- }
-
- @Override
- public String getName() {
- return name;
- }
-
- @Override
- public T getValue() {
- return value;
- }
-
- public void setValue(T value) {
- this.value = value;
- }
-
- @Override
- public String toString() {
- return String.format("ClaimValueWrapper[@%s], name=%s, value[%s]=%s", Integer.toHexString(hashCode()),
- name, value.getClass(), value);
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/DefaultJWTCallerPrincipal.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/DefaultJWTCallerPrincipal.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/DefaultJWTCallerPrincipal.java
deleted file mode 100644
index 2559b1e..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/DefaultJWTCallerPrincipal.java
+++ /dev/null
@@ -1,334 +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.tomee.microprofile.jwt;
-
-import org.eclipse.microprofile.jwt.Claims;
-import org.jose4j.jwt.JwtClaims;
-import org.jose4j.jwt.MalformedClaimException;
-
-import javax.json.Json;
-import javax.json.JsonArray;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonNumber;
-import javax.json.JsonObject;
-import javax.json.JsonObjectBuilder;
-import javax.json.JsonValue;
-import javax.security.auth.Subject;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * A default implementation of JWTCallerPrincipal using jose4j
- * Another implementation could use nimbus and another plain JSON-P
- */
-public class DefaultJWTCallerPrincipal extends JWTCallerPrincipal {
-
- private static Logger logger = Logger.getLogger(DefaultJWTCallerPrincipal.class.getName());
- private String jwt;
- private String type;
- private JwtClaims claimsSet;
-
- /**
- * Create the DefaultJWTCallerPrincipal from the parsed JWT token and the extracted principal name
- *
- * @param jwt - the parsed JWT token representation
- * @param name - the extracted unqiue name to use as the principal name; from "upn", "preferred_username" or "sub" claim
- */
- public DefaultJWTCallerPrincipal(String jwt, String type, JwtClaims claimsSet, String name) {
- super(name);
- this.jwt = jwt;
- this.type = type;
- this.claimsSet = claimsSet;
- fixJoseTypes();
- }
-
- @Override
- public Set<String> getAudience() {
- Set<String> audSet = new HashSet<>();
- try {
- List<String> audList = claimsSet.getStringListClaimValue("aud");
- if (audList != null) {
- audSet.addAll(audList);
- }
- } catch (MalformedClaimException e) {
- try {
- String aud = claimsSet.getStringClaimValue("aud");
- audSet.add(aud);
- } catch (MalformedClaimException e1) {
- }
- }
- return audSet;
- }
-
- @Override
- public Set<String> getGroups() {
- HashSet<String> groups = new HashSet<>();
- try {
- List<String> globalGroups = claimsSet.getStringListClaimValue("groups");
- if (globalGroups != null) {
- groups.addAll(globalGroups);
- }
- } catch (MalformedClaimException e) {
- e.printStackTrace();
- }
- return groups;
- }
-
-
- @Override
- public Set<String> getClaimNames() {
- return new HashSet<>(claimsSet.getClaimNames());
- }
-
- @Override
- public Object getClaim(String claimName) {
- Claims claimType = Claims.UNKNOWN;
- Object claim = null;
- try {
- claimType = Claims.valueOf(claimName);
- } catch (IllegalArgumentException e) {
- }
- // Handle the jose4j NumericDate types and
- switch (claimType) {
- case exp:
- case iat:
- case auth_time:
- case nbf:
- case updated_at:
- try {
- claim = claimsSet.getClaimValue(claimType.name(), Long.class);
- if (claim == null) {
- claim = new Long(0);
- }
- } catch (MalformedClaimException e) {
- }
- break;
- case groups:
- claim = getGroups();
- break;
- case aud:
- claim = getAudience();
- break;
- case UNKNOWN:
- claim = claimsSet.getClaimValue(claimName);
- break;
- default:
- claim = claimsSet.getClaimValue(claimType.name());
- }
- return claim;
- }
-
- @Override
- public boolean implies(Subject subject) {
- return false;
- }
-
- public String toString() {
- return toString(false);
- }
-
- /**
- * TODO: showAll is ignored and currently assumed true
- *
- * @param showAll - should all claims associated with the JWT be displayed or should only those defined in the
- * JsonWebToken interface be displayed.
- * @return JWTCallerPrincipal string view
- */
- @Override
- public String toString(boolean showAll) {
- String toString = "DefaultJWTCallerPrincipal{" +
- "id='" + getTokenID() + '\'' +
- ", name='" + getName() + '\'' +
- ", expiration=" + getExpirationTime() +
- ", notBefore=" + getClaim(Claims.nbf.name()) +
- ", issuedAt=" + getIssuedAtTime() +
- ", issuer='" + getIssuer() + '\'' +
- ", audience=" + getAudience() +
- ", subject='" + getSubject() + '\'' +
- ", type='" + type + '\'' +
- ", issuedFor='" + getClaim("azp") + '\'' +
- ", authTime=" + getClaim("auth_time") +
- ", givenName='" + getClaim("given_name") + '\'' +
- ", familyName='" + getClaim("family_name") + '\'' +
- ", middleName='" + getClaim("middle_name") + '\'' +
- ", nickName='" + getClaim("nickname") + '\'' +
- ", preferredUsername='" + getClaim("preferred_username") + '\'' +
- ", email='" + getClaim("email") + '\'' +
- ", emailVerified=" + getClaim(Claims.email_verified.name()) +
- ", allowedOrigins=" + getClaim("allowedOrigins") +
- ", updatedAt=" + getClaim("updated_at") +
- ", acr='" + getClaim("acr") + '\'';
- StringBuilder tmp = new StringBuilder(toString);
- tmp.append(", groups=[");
- for (String group : getGroups()) {
- tmp.append(group);
- tmp.append(',');
- }
- tmp.setLength(tmp.length() - 1);
- tmp.append("]}");
- return tmp.toString();
- }
-
- /**
- * Convert the types jose4j uses for address, sub_jwk, and jwk
- */
- private void fixJoseTypes() {
- if (claimsSet.hasClaim(Claims.address.name())) {
- replaceMap(Claims.address.name());
- }
- if (claimsSet.hasClaim(Claims.jwk.name())) {
- replaceMap(Claims.jwk.name());
- }
- if (claimsSet.hasClaim(Claims.sub_jwk.name())) {
- replaceMap(Claims.sub_jwk.name());
- }
- // Handle custom claims
- Set<String> customClaimNames = filterCustomClaimNames(claimsSet.getClaimNames());
- for (String name : customClaimNames) {
- Object claimValue = claimsSet.getClaimValue(name);
- Class claimType = claimValue.getClass();
- if (claimValue instanceof List) {
- replaceList(name);
- } else if (claimValue instanceof Map) {
- replaceMap(name);
- } else if (claimValue instanceof Number) {
- replaceNumber(name);
- }
- }
- }
-
- /**
- * Determine the custom claims in the set
- *
- * @param claimNames - the current set of claim names in this token
- * @return the possibly empty set of names for non-Claims claims
- */
- private Set<String> filterCustomClaimNames(Collection<String> claimNames) {
- HashSet<String> customNames = new HashSet<>(claimNames);
- for (Claims claim : Claims.values()) {
- customNames.remove(claim.name());
- }
- return customNames;
- }
-
- /**
- * Replace the jose4j Map<String,Object> with a JsonObject
- *
- * @param name - claim name
- */
- private void replaceMap(String name) {
- try {
- Map<String, Object> map = claimsSet.getClaimValue(name, Map.class);
- JsonObject jsonObject = replaceMap(map);
- claimsSet.setClaim(name, jsonObject);
- } catch (MalformedClaimException e) {
- logger.log(Level.WARNING, "replaceMap failure for: " + name, e);
- }
- }
-
- private JsonObject replaceMap(Map<String, Object> map) {
- JsonObjectBuilder builder = Json.createObjectBuilder();
- for (Map.Entry<String, Object> entry : map.entrySet()) {
- Object entryValue = entry.getValue();
- if (entryValue instanceof Map) {
- JsonObject entryJsonObject = replaceMap((Map<String, Object>) entryValue);
- builder.add(entry.getKey(), entryJsonObject);
- } else if (entryValue instanceof List) {
- JsonArray array = (JsonArray) wrapValue(entryValue);
- builder.add(entry.getKey(), array);
- } else if (entryValue instanceof Long || entryValue instanceof Integer) {
- long lvalue = ((Number) entryValue).longValue();
- builder.add(entry.getKey(), lvalue);
- } else if (entryValue instanceof Double || entryValue instanceof Float) {
- double dvalue = ((Number) entryValue).doubleValue();
- builder.add(entry.getKey(), dvalue);
- } else if (entryValue instanceof Boolean) {
- boolean flag = ((Boolean) entryValue).booleanValue();
- builder.add(entry.getKey(), flag);
- } else if (entryValue instanceof String) {
- builder.add(entry.getKey(), entryValue.toString());
- }
- }
- return builder.build();
- }
-
- private JsonValue wrapValue(Object value) {
- JsonValue jsonValue = null;
- if (value instanceof Number) {
- Number number = (Number) value;
- if ((number instanceof Long) || (number instanceof Integer)) {
- jsonValue = Json.createObjectBuilder()
- .add("tmp", number.longValue())
- .build()
- .getJsonNumber("tmp");
- } else {
- jsonValue = Json.createObjectBuilder()
- .add("tmp", number.doubleValue())
- .build()
- .getJsonNumber("tmp");
- }
- } else if (value instanceof Boolean) {
- Boolean flag = (Boolean) value;
- jsonValue = flag ? JsonValue.TRUE : JsonValue.FALSE;
- } else if (value instanceof List) {
- JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
- List list = (List) value;
- for (Object element : list) {
- if (element instanceof String) {
- arrayBuilder.add(element.toString());
- } else {
- JsonValue jvalue = wrapValue(element);
- arrayBuilder.add(jvalue);
- }
- }
- jsonValue = arrayBuilder.build();
- }
- return jsonValue;
- }
-
-
- /**
- * Replace the jose4j List<?> with a JsonArray
- *
- * @param name - claim name
- */
- private void replaceList(String name) {
- try {
- List list = claimsSet.getClaimValue(name, List.class);
- JsonArray array = (JsonArray) wrapValue(list);
- claimsSet.setClaim(name, array);
- } catch (MalformedClaimException e) {
- logger.log(Level.WARNING, "replaceList failure for: " + name, e);
- }
- }
-
- private void replaceNumber(String name) {
- try {
- Number number = claimsSet.getClaimValue(name, Number.class);
- JsonNumber jsonNumber = (JsonNumber) wrapValue(number);
- claimsSet.setClaim(name, jsonNumber);
- } catch (MalformedClaimException e) {
- logger.log(Level.WARNING, "replaceNumber failure for: " + name, e);
- }
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/DefaultJWTCallerPrincipalFactory.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/DefaultJWTCallerPrincipalFactory.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/DefaultJWTCallerPrincipalFactory.java
deleted file mode 100644
index 9c0a870..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/DefaultJWTCallerPrincipalFactory.java
+++ /dev/null
@@ -1,86 +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.tomee.microprofile.jwt;
-
-import org.eclipse.microprofile.jwt.Claims;
-import org.jose4j.jwa.AlgorithmConstraints;
-import org.jose4j.jws.AlgorithmIdentifiers;
-import org.jose4j.jwt.JwtClaims;
-import org.jose4j.jwt.MalformedClaimException;
-import org.jose4j.jwt.NumericDate;
-import org.jose4j.jwt.consumer.InvalidJwtException;
-import org.jose4j.jwt.consumer.JwtConsumer;
-import org.jose4j.jwt.consumer.JwtConsumerBuilder;
-import org.jose4j.jwt.consumer.JwtContext;
-
-/**
- * A default implementation of the abstract JWTCallerPrincipalFactory that uses the Keycloak token parsing classes.
- */
-public class DefaultJWTCallerPrincipalFactory extends JWTCallerPrincipalFactory {
-
- /**
- * Tries to load the JWTAuthContextInfo from CDI if the class level authContextInfo has not been set.
- */
- public DefaultJWTCallerPrincipalFactory() {
- }
-
- @Override
- public JWTCallerPrincipal parse(final String token, final JWTAuthContextInfo authContextInfo) throws ParseException {
- JWTCallerPrincipal principal = null;
-
- try {
- JwtConsumerBuilder builder = new JwtConsumerBuilder()
- .setRequireExpirationTime()
- .setRequireSubject()
- .setSkipDefaultAudienceValidation()
- .setExpectedIssuer(authContextInfo.getIssuedBy())
- .setVerificationKey(authContextInfo.getSignerKey())
- .setJwsAlgorithmConstraints(
- new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.WHITELIST,
- AlgorithmIdentifiers.RSA_USING_SHA256));
- if (authContextInfo.getExpGracePeriodSecs() > 0) {
- builder.setAllowedClockSkewInSeconds(authContextInfo.getExpGracePeriodSecs());
- } else {
- builder.setEvaluationTime(NumericDate.fromSeconds(0));
- }
-
- JwtConsumer jwtConsumer = builder.build();
- JwtContext jwtContext = jwtConsumer.process(token);
- String type = jwtContext.getJoseObjects().get(0).getHeader("typ");
- // Validate the JWT and process it to the Claims
- jwtConsumer.processContext(jwtContext);
- JwtClaims claimsSet = jwtContext.getJwtClaims();
-
- // We have to determine the unique name to use as the principal name. It comes from upn, preferred_username, sub in that order
- String principalName = claimsSet.getClaimValue("upn", String.class);
- if (principalName == null) {
- principalName = claimsSet.getClaimValue("preferred_username", String.class);
- if (principalName == null) {
- principalName = claimsSet.getSubject();
- }
- }
- claimsSet.setClaim(Claims.raw_token.name(), token);
- principal = new DefaultJWTCallerPrincipal(token, type, claimsSet, principalName);
- } catch (InvalidJwtException e) {
- throw new ParseException("Failed to verify token", e);
- } catch (MalformedClaimException e) {
- throw new ParseException("Failed to verify token claims", e);
- }
-
- return principal;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTAuthContextInfo.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTAuthContextInfo.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTAuthContextInfo.java
deleted file mode 100644
index a93e2cc..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTAuthContextInfo.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.tomee.microprofile.jwt;
-
-import java.security.interfaces.RSAPublicKey;
-
-/**
- * The public key and expected issuer needed to validate a token.
- */
-public class JWTAuthContextInfo {
- private RSAPublicKey signerKey;
- private String issuedBy;
- private int expGracePeriodSecs = 60;
-
- public JWTAuthContextInfo() {
- }
-
- public JWTAuthContextInfo(RSAPublicKey signerKey, String issuedBy) {
- this.signerKey = signerKey;
- this.issuedBy = issuedBy;
- }
-
- public JWTAuthContextInfo(JWTAuthContextInfo orig) {
- this.signerKey = orig.signerKey;
- this.issuedBy = orig.issuedBy;
- this.expGracePeriodSecs = orig.expGracePeriodSecs;
- }
-
- public RSAPublicKey getSignerKey() {
- return signerKey;
- }
-
- public void setSignerKey(RSAPublicKey signerKey) {
- this.signerKey = signerKey;
- }
-
- public String getIssuedBy() {
- return issuedBy;
- }
-
- public void setIssuedBy(String issuedBy) {
- this.issuedBy = issuedBy;
- }
-
- public int getExpGracePeriodSecs() {
- return expGracePeriodSecs;
- }
-
- public void setExpGracePeriodSecs(int expGracePeriodSecs) {
- this.expGracePeriodSecs = expGracePeriodSecs;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTAuthContextInfoProvider.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTAuthContextInfoProvider.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTAuthContextInfoProvider.java
deleted file mode 100644
index a173ea2..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTAuthContextInfoProvider.java
+++ /dev/null
@@ -1,59 +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.tomee.microprofile.jwt;
-
-import javax.enterprise.context.Dependent;
-import javax.enterprise.inject.Produces;
-import java.security.interfaces.RSAPublicKey;
-import java.util.Optional;
-
-@Dependent
-public class JWTAuthContextInfoProvider {
-
- @Produces
- Optional<JWTAuthContextInfo> getOptionalContextInfo() {
- JWTAuthContextInfo contextInfo = new JWTAuthContextInfo();
-
- // todo use MP Config to load the configuration
- contextInfo.setIssuedBy("https://server.example.com");
- RSAPublicKey pk = null;
- try {
- pk = (RSAPublicKey) KeyUtils.decodePublicKey("-----BEGIN RSA PUBLIC KEY-----\n" +
- "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEq\n" +
- "Fyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwR\n" +
- "TYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5e\n" +
- "UF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9\n" +
- "AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYn\n" +
- "sIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9x\n" +
- "nQIDAQAB\n" +
- "-----END RSA PUBLIC KEY-----\n");
-
- } catch (final Exception e) {
- e.printStackTrace();
- // todo better handling
- throw new RuntimeException(e);
- }
- contextInfo.setSignerKey(pk);
-
- return Optional.of(contextInfo);
- }
-
- @Produces
- JWTAuthContextInfo getContextInfo() {
- return getOptionalContextInfo().get();
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipal.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipal.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipal.java
deleted file mode 100644
index e130213..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipal.java
+++ /dev/null
@@ -1,59 +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.tomee.microprofile.jwt;
-
-
-import org.eclipse.microprofile.jwt.JsonWebToken;
-
-import java.util.Optional;
-
-/**
- * An abstract CallerPrincipal implementation that provides access to the JWT claims that are required by
- * the microprofile token.
- */
-public abstract class JWTCallerPrincipal implements JsonWebToken {
-
- private String name;
-
- /**
- * Create a JWTCallerPrincipal with the caller's name
- *
- * @param name - caller's name
- */
- public JWTCallerPrincipal(String name) {
- this.name = name;
- }
-
- @Override
- public String getName() {
- return name;
- }
-
- /**
- * Generate a human readable version of the caller principal and associated JWT.
- *
- * @param showAll - should all claims associated with the JWT be displayed or should only those defined in the
- * JsonWebToken interface be displayed.
- * @return human readable presentation of the caller principal and associated JWT.
- */
- public abstract String toString(boolean showAll);
-
- public <T> Optional<T> claim(final String claimName) {
- final T claim = (T) getClaim(claimName);
- return Optional.ofNullable(claim);
- }
-}
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipalFactory.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipalFactory.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipalFactory.java
deleted file mode 100644
index cb00cc5..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipalFactory.java
+++ /dev/null
@@ -1,124 +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.tomee.microprofile.jwt;
-
-import java.net.URL;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.ServiceLoader;
-
-/**
- * The factory class that provides the token string to JWTCallerPrincipal parsing for a given implementation.
- */
-public abstract class JWTCallerPrincipalFactory {
- private static JWTCallerPrincipalFactory instance;
-
- /**
- * Obtain the JWTCallerPrincipalFactory that has been set or by using the ServiceLoader pattern.
- *
- * @return the factory instance
- * @see #setInstance(JWTCallerPrincipalFactory)
- */
- public static JWTCallerPrincipalFactory instance() {
- if (instance == null) {
- synchronized (JWTCallerPrincipalFactory.class) {
- if (instance != null) {
- return instance;
- }
-
- ClassLoader cl = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
- @Override
- public ClassLoader run() {
- return Thread.currentThread().getContextClassLoader();
- }
- });
- if (cl == null) {
- cl = JWTCallerPrincipalFactory.class.getClassLoader();
- }
-
- JWTCallerPrincipalFactory newInstance = loadSpi(cl);
-
- if (newInstance == null && cl != JWTCallerPrincipalFactory.class.getClassLoader()) {
- cl = JWTCallerPrincipalFactory.class.getClassLoader();
- newInstance = loadSpi(cl);
- }
- if (newInstance == null) {
- throw new IllegalStateException("No JWTCallerPrincipalFactory implementation found!");
- }
-
- instance = newInstance;
- }
- }
-
- return instance;
- }
-
- /**
- * Look for a JWTCallerPrincipalFactory service implementation using the ServiceLoader.
- *
- * @param cl - the ClassLoader to pass into the {@link ServiceLoader#load(Class, ClassLoader)} method.
- * @return the JWTCallerPrincipalFactory if found, null otherwise
- */
- private static JWTCallerPrincipalFactory loadSpi(ClassLoader cl) {
- if (cl == null) {
- return null;
- }
-
- // start from the root CL and go back down to the TCCL
- JWTCallerPrincipalFactory instance = loadSpi(cl.getParent());
-
- if (instance == null) {
- ServiceLoader<JWTCallerPrincipalFactory> sl = ServiceLoader.load(JWTCallerPrincipalFactory.class, cl);
- URL u = cl.getResource("/META-INF/services/org.apache.tomee.microprofile.jwt.JWTCallerPrincipalFactory");
- System.out.printf("JWTCallerPrincipalFactory, cl=%s, u=%s, sl=%s\n", cl, u, sl);
- try {
- for (JWTCallerPrincipalFactory spi : sl) {
- if (instance != null) {
- throw new IllegalStateException(
- "Multiple JWTCallerPrincipalFactory implementations found: "
- + spi.getClass().getName() + " and "
- + instance.getClass().getName());
- } else {
- System.out.printf("sl=%s, loaded=%s\n", sl, spi);
- instance = spi;
- }
- }
- } catch (Throwable e) {
- System.err.printf("Warning: %s\n", e.getMessage());
- }
- }
- return instance;
- }
-
- /**
- * Set the instance. It is used by OSGi environment where service loader pattern is not supported.
- *
- * @param resolver the instance to use.
- */
- public static void setInstance(JWTCallerPrincipalFactory resolver) {
- instance = resolver;
- }
-
- /**
- * Parse the given bearer token string into a JWTCallerPrincipal instance.
- *
- * @param token - the bearer token provided for authorization
- * @return A JWTCallerPrincipal representation for the token.
- * @throws ParseException on parse or verification failure.
- */
- public abstract JWTCallerPrincipal parse(String token, JWTAuthContextInfo authContextInfo) throws ParseException;
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JsonValueProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JsonValueProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JsonValueProducer.java
deleted file mode 100644
index 355b1d5..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JsonValueProducer.java
+++ /dev/null
@@ -1,111 +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.tomee.microprofile.jwt;
-
-import org.eclipse.microprofile.jwt.Claim;
-import org.eclipse.microprofile.jwt.Claims;
-
-import javax.enterprise.inject.Produces;
-import javax.enterprise.inject.spi.InjectionPoint;
-import javax.json.JsonArray;
-import javax.json.JsonNumber;
-import javax.json.JsonObject;
-import javax.json.JsonString;
-import javax.json.JsonValue;
-import java.lang.annotation.Annotation;
-import java.util.Optional;
-import java.util.logging.Logger;
-
-/**
- * A producer for JsonValue injection types
- */
-public class JsonValueProducer {
- private static Logger log = Logger.getLogger(JsonValueProducer.class.getName());
-
- @Produces
- @Claim("")
- public JsonString getJsonString(InjectionPoint ip) {
- return getValue(ip);
- }
-
- @Produces
- @Claim("")
- public Optional<JsonString> getOptionalJsonString(InjectionPoint ip) {
- return getOptionalValue(ip);
- }
-
- @Produces
- @Claim("")
- public JsonNumber getJsonNumber(InjectionPoint ip) {
- return getValue(ip);
- }
-
- @Produces
- @Claim("")
- public Optional<JsonNumber> getOptionalJsonNumber(InjectionPoint ip) {
- return getOptionalValue(ip);
- }
-
- @Produces
- @Claim("")
- public JsonArray getJsonArray(InjectionPoint ip) {
- return getValue(ip);
- }
-
- @Produces
- @Claim("")
- public Optional<JsonArray> getOptionalJsonArray(InjectionPoint ip) {
- return getOptionalValue(ip);
- }
-
- @Produces
- @Claim("")
- public JsonObject getJsonObject(InjectionPoint ip) {
- return getValue(ip);
- }
-
- @Produces
- @Claim("")
- public Optional<JsonObject> getOptionalJsonObject(InjectionPoint ip) {
- return getOptionalValue(ip);
- }
-
- public <T extends JsonValue> T getValue(InjectionPoint ip) {
- log.fine(String.format("JsonValueProducer(%s).produce", ip));
- String name = getName(ip);
- T jsonValue = (T) MPJWTProducer.generalJsonValueProducer(name);
- return jsonValue;
- }
-
- public <T extends JsonValue> Optional<T> getOptionalValue(InjectionPoint ip) {
- log.fine(String.format("JsonValueProducer(%s).produce", ip));
- String name = getName(ip);
- T jsonValue = (T) MPJWTProducer.generalJsonValueProducer(name);
- return Optional.ofNullable(jsonValue);
- }
-
- String getName(InjectionPoint ip) {
- String name = null;
- for (Annotation ann : ip.getQualifiers()) {
- if (ann instanceof Claim) {
- Claim claim = (Claim) ann;
- name = claim.standard() == Claims.UNKNOWN ? claim.value() : claim.standard().name();
- }
- }
- return name;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTCDIExtension.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTCDIExtension.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTCDIExtension.java
deleted file mode 100644
index aa15a33..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTCDIExtension.java
+++ /dev/null
@@ -1,391 +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.tomee.microprofile.jwt;
-
-import org.eclipse.microprofile.jwt.Claim;
-import org.eclipse.microprofile.jwt.Claims;
-
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.context.SessionScoped;
-import javax.enterprise.event.Observes;
-import javax.enterprise.inject.spi.AfterBeanDiscovery;
-import javax.enterprise.inject.spi.AfterDeploymentValidation;
-import javax.enterprise.inject.spi.BeanAttributes;
-import javax.enterprise.inject.spi.BeanManager;
-import javax.enterprise.inject.spi.BeforeBeanDiscovery;
-import javax.enterprise.inject.spi.DeploymentException;
-import javax.enterprise.inject.spi.Extension;
-import javax.enterprise.inject.spi.InjectionPoint;
-import javax.enterprise.inject.spi.ProcessBeanAttributes;
-import javax.enterprise.inject.spi.ProcessInjectionPoint;
-import javax.enterprise.inject.spi.ProcessProducer;
-import javax.inject.Provider;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Optional;
-import java.util.Set;
-import java.util.logging.Logger;
-
-/**
- * A CDI extension that provides a producer for the current authenticated JsonWebToken based on a thread
- * local value that is managed by the {@link JWTAuthMechanism} request
- * authentication handler.
- * <p>
- * This also installs the producer methods for the discovered:
- * <ul>
- * <li>@Claim ClaimValue<T> injection sites.</li>
- * <li>@Claim raw type<T> injection sites.</li>
- * <li>@Claim JsonValue injection sites.</li>
- * </ul>
- *
- * @see JWTAuthMechanism
- */
-public class MPJWTCDIExtension implements Extension {
- private static Logger log = Logger.getLogger(MPJWTCDIExtension.class.getName());
-
- /**
- * Register the MPJWTProducer JsonWebToken producer bean
- *
- * @param bbd before discovery event
- * @param beanManager cdi bean manager
- */
- public void observeBeforeBeanDiscovery(@Observes BeforeBeanDiscovery bbd, BeanManager beanManager) {
- log.fine(String.format("MPJWTExtension(), added JWTPrincipalProducer"));
- bbd.addAnnotatedType(beanManager.createAnnotatedType(TCKTokenParser.class));
- bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTFilter.class));
- bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTInitializer.class));
- bbd.addAnnotatedType(beanManager.createAnnotatedType(JWTAuthContextInfoProvider.class));
- bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTProducer.class));
- bbd.addAnnotatedType(beanManager.createAnnotatedType(RawClaimTypeProducer.class));
- bbd.addAnnotatedType(beanManager.createAnnotatedType(ClaimValueProducer.class));
- bbd.addAnnotatedType(beanManager.createAnnotatedType(JsonValueProducer.class));
- }
-
- /**
- * Replace the general producer method BeanAttributes with one bound to the collected injection site
- * types to properly reflect all of the type locations the producer method applies to.
- *
- * @param pba the ProcessBeanAttributes
- * @see ClaimProviderBeanAttributes
- */
- public void addTypeToClaimProducer(@Observes ProcessBeanAttributes pba) {
- if (pba.getAnnotated().isAnnotationPresent(Claim.class)) {
- Claim claim = pba.getAnnotated().getAnnotation(Claim.class);
- if (claim.value().length() == 0 && claim.standard() == Claims.UNKNOWN) {
- log.fine(String.format("addTypeToClaimProducer: %s\n", pba.getAnnotated()));
- BeanAttributes delegate = pba.getBeanAttributes();
- String name = delegate.getName();
- if (delegate.getTypes().contains(Optional.class)) {
- if (providerOptionalTypes.size() == 0) {
- providerOptionalTypes.add(Optional.class);
- }
- pba.setBeanAttributes(new ClaimProviderBeanAttributes(delegate, providerOptionalTypes, providerQualifiers));
- // This is
- } else if (name != null && name.startsWith("RawClaimTypeProducer#")) {
- if (rawTypes.size() == 0) {
- rawTypes.add(Object.class);
- }
- pba.setBeanAttributes(new ClaimProviderBeanAttributes(delegate, rawTypes, rawTypeQualifiers));
- log.fine(String.format("Setup RawClaimTypeProducer BeanAttributes"));
- }
- }
- }
- }
-
- public void afterDeploymentValidation(@Observes AfterDeploymentValidation event, BeanManager beanManager) {
- }
-
- void doProcessProducers(@Observes ProcessProducer pp) {
- }
-
- /**
- * Handle the non-{@linkplain Provider}, {@linkplain org.eclipse.microprofile.jwt.ClaimValue}, and
- * {@linkplain javax.json.JsonValue} claim injection types.
- *
- * @param pip - the injection point event information
- * @see RawClaimTypeProducer
- */
- void processClaimInjections(@Observes ProcessInjectionPoint pip) {
- log.fine(String.format("pipRaw: %s", pip.getInjectionPoint()));
- InjectionPoint ip = pip.getInjectionPoint();
- if (ip.getAnnotated().isAnnotationPresent(Claim.class)) {
- Claim claim = ip.getAnnotated().getAnnotation(Claim.class);
- if (ip.getType() instanceof Class) {
- Class rawClass = (Class) ip.getType();
- // Primative types
- if (Modifier.isFinal(rawClass.getModifiers())) {
- rawTypes.add(ip.getType());
- rawTypeQualifiers.add(claim);
- log.fine(String.format("+++ Added Claim raw type: %s", ip.getType()));
- Class declaringClass = ip.getMember().getDeclaringClass();
- Annotation[] appScoped = declaringClass.getAnnotationsByType(ApplicationScoped.class);
- Annotation[] sessionScoped = declaringClass.getAnnotationsByType(SessionScoped.class);
- if ((appScoped != null && appScoped.length > 0) || (sessionScoped != null && sessionScoped.length > 0)) {
- String err = String.format("A raw type cannot be injected into application/session scope: IP=%s", ip);
- pip.addDefinitionError(new DeploymentException(err));
- }
- }
- // This handles collections of primative types
- } else if (isRawParameterizedType(ip.getType())) {
- log.fine(String.format("+++ Added Claim ParameterizedType: %s", ip.getType()));
- rawTypes.add(ip.getType());
- rawTypeQualifiers.add(claim);
- }
- } else {
- log.fine(String.format("Skipping pip: %s, type: %s/%s", ip, ip.getType(), ip.getType().getClass()));
- }
- }
-
- /**
- * Collect the types of all {@linkplain Provider} injection points annotated with {@linkplain Claim}.
- *
- * @param pip - the injection point event information
- */
- void processClaimProviderInjections(@Observes ProcessInjectionPoint<?, ? extends Provider> pip) {
- log.fine(String.format("pip: %s", pip.getInjectionPoint()));
- final InjectionPoint ip = pip.getInjectionPoint();
- if (ip.getAnnotated().isAnnotationPresent(Claim.class)) {
- Claim claim = ip.getAnnotated().getAnnotation(Claim.class);
- if (claim.value().length() == 0 && claim.standard() == Claims.UNKNOWN) {
- pip.addDefinitionError(new DeploymentException("@Claim at: " + ip + " has no name or valid standard enum setting"));
- }
- boolean usesEnum = claim.standard() != Claims.UNKNOWN;
- final String claimName = usesEnum ? claim.standard().name() : claim.value();
- log.fine(String.format("Checking Provider Claim(%s), ip: %s", claimName, ip));
- ClaimIP claimIP = claims.get(claimName);
- Type matchType = ip.getType();
- // The T from the Provider<T> injection site
- Type actualType = ((ParameterizedType) matchType).getActualTypeArguments()[0];
- // Don't add Optional or JsonValue as this is handled specially
- if (!optionalOrJsonValue(actualType)) {
- rawTypes.add(actualType);
- } else if (!actualType.getTypeName().startsWith("javax.json.Json")) {
- // Validate that this is not an Optional<JsonValue>
- Type innerType = ((ParameterizedType) actualType).getActualTypeArguments()[0];
- if (!innerType.getTypeName().startsWith("javax.json.Json")) {
- providerOptionalTypes.add(actualType);
- providerQualifiers.add(claim);
- }
- }
- rawTypeQualifiers.add(claim);
- ClaimIPType key = new ClaimIPType(claimName, actualType);
- if (claimIP == null) {
- claimIP = new ClaimIP(actualType, actualType, false, claim);
- claimIP.setProviderSite(true);
- claims.put(key, claimIP);
- }
- claimIP.getInjectionPoints().add(ip);
- log.fine(String.format("+++ Added Provider Claim(%s) ip: %s", claimName, ip));
-
- }
- }
-
- /**
- * Create producer methods for each ClaimValue injection site
- *
- * @param event - AfterBeanDiscovery
- * @param beanManager - CDI bean manager
- */
- void observesAfterBeanDiscovery(@Observes final AfterBeanDiscovery event, final BeanManager beanManager) {
- log.fine(String.format("observesAfterBeanDiscovery, %s", claims));
- installClaimValueProducerMethodsViaSyntheticBeans(event, beanManager);
-
- //installClaimValueProducesViaTemplateType(event, beanManager);
- }
-
- /**
- * Create a synthetic bean with a custom Producer for the non-Provider injection sites.
- *
- * @param event - AfterBeanDiscovery
- * @param beanManager - CDI bean manager
- */
- private void installClaimValueProducerMethodsViaSyntheticBeans(final AfterBeanDiscovery event, final BeanManager beanManager) {
-
- }
-
- private boolean optionalOrJsonValue(Type type) {
- boolean isOptionOrJson = type.getTypeName().startsWith(Optional.class.getTypeName())
- | type.getTypeName().startsWith("javax.json.Json");
- return isOptionOrJson;
- }
-
- private boolean isRawParameterizedType(Type type) {
- boolean isRawParameterizedType = false;
- if (type instanceof ParameterizedType) {
- ParameterizedType ptype = ParameterizedType.class.cast(type);
- Type rawType = ptype.getRawType();
- String rawTypeName = rawType.getTypeName();
- isRawParameterizedType = !rawTypeName.startsWith("org.eclipse.microprofile.jwt");
- }
- return isRawParameterizedType;
- }
-
- /**
- * A map of claim,type pairs to the injection site information
- */
- private HashMap<ClaimIPType, ClaimIP> claims = new HashMap<>();
-
- private Set<Type> providerOptionalTypes = new HashSet<>();
-
- private Set<Type> providerTypes = new HashSet<>();
-
- private Set<Type> rawTypes = new HashSet<>();
-
- private Set<Annotation> rawTypeQualifiers = new HashSet<>();
-
- private Set<Annotation> providerQualifiers = new HashSet<>();
-
- /**
- * A key for a claim,injection site type pair
- */
- public static class ClaimIPType implements Comparable<ClaimIPType> {
- public ClaimIPType(String claimName, Type ipType) {
- this.claimName = claimName;
- this.ipType = ipType;
- }
-
- /**
- * Order the @Claim ClaimValue<T> on the @Claim.value and then T type name
- *
- * @param o - ClaimIP to compare to
- * @return the ordering of this claim relative to o
- */
- @Override
- public int compareTo(ClaimIPType o) {
- int compareTo = claimName.compareTo(o.claimName);
- if (compareTo == 0) {
- compareTo = ipType.getTypeName().compareTo(o.ipType.getTypeName());
- }
- return compareTo;
- }
-
- private String claimName;
-
- private Type ipType;
- }
-
- /**
- * The representation of an @Claim annotated injection site
- */
- public static class ClaimIP {
- /**
- * Create a ClaimIP from the injection site information
- *
- * @param matchType - the outer type of the injection site
- * @param valueType - the parameterized type of the injection site
- * @param isOptional - is the injection site an Optional
- * @param claim - the Claim qualifier
- */
- public ClaimIP(Type matchType, Type valueType, boolean isOptional, Claim claim) {
- this.matchType = matchType;
- this.valueType = valueType;
- this.claim = claim;
- }
-
- public Type getMatchType() {
- return matchType;
- }
-
- public String getClaimName() {
- return claim.standard() == Claims.UNKNOWN ? claim.value() : claim.standard().name();
- }
-
- public Claim getClaim() {
- return claim;
- }
-
- public Type getValueType() {
- return valueType;
- }
-
- public boolean isOptional() {
- return isOptional;
- }
-
- public boolean isProviderSite() {
- return isProviderSite;
- }
-
- public void setProviderSite(boolean providerSite) {
- this.isProviderSite = providerSite;
- }
-
- public boolean isNonStandard() {
- return isNonStandard;
- }
-
- public void setNonStandard(boolean nonStandard) {
- isNonStandard = nonStandard;
- }
-
- public boolean isJsonValue() {
- return isJsonValue;
- }
-
- public void setJsonValue(boolean jsonValue) {
- isJsonValue = jsonValue;
- }
-
- public Set<InjectionPoint> getInjectionPoints() {
- return injectionPoints;
- }
-
- @Override
- public String toString() {
- return "ClaimIP{" +
- "type=" + matchType +
- ", claim=" + claim +
- ", ips=" + injectionPoints +
- '}';
- }
-
- /**
- * The injection site value type
- */
- private Type matchType;
-
- /**
- * The actual type of of the ParameterizedType matchType
- */
- private Type valueType;
-
- /**
- * Is valueType actually wrapped in an Optional
- */
- private boolean isOptional;
-
- private boolean isProviderSite;
-
- private boolean isNonStandard;
-
- private boolean isJsonValue;
-
- /**
- * The injection site @Claim annotation value
- */
- private Claim claim;
-
- /**
- * The location that share the @Claim/type combination
- */
- private HashSet<InjectionPoint> injectionPoints = new HashSet<>();
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
index a8f7cb4..0c80696 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
@@ -16,6 +16,10 @@
*/
package org.apache.tomee.microprofile.jwt;
+import org.apache.tomee.microprofile.jwt.cdi.MPJWTProducer;
+import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfo;
+import org.apache.tomee.microprofile.jwt.principal.DefaultJWTCallerPrincipalFactory;
+import org.apache.tomee.microprofile.jwt.principal.JWTCallerPrincipalFactory;
import org.eclipse.microprofile.jwt.JsonWebToken;
import javax.inject.Inject;
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTProducer.java
deleted file mode 100644
index 195f323..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTProducer.java
+++ /dev/null
@@ -1,196 +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.tomee.microprofile.jwt;
-
-import org.eclipse.microprofile.jwt.ClaimValue;
-import org.eclipse.microprofile.jwt.JsonWebToken;
-
-import javax.annotation.PostConstruct;
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.context.Destroyed;
-import javax.enterprise.context.Initialized;
-import javax.enterprise.context.RequestScoped;
-import javax.enterprise.event.Observes;
-import javax.enterprise.inject.Produces;
-import javax.json.Json;
-import javax.json.JsonArray;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonObject;
-import javax.json.JsonObjectBuilder;
-import javax.json.JsonValue;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.logging.Logger;
-
-/**
- * A class that tracks the current validated MP-JWT and associated JsonWebToken via a thread
- * local to provide a @RequestScoped JsonWebToken producer method.
- * <p>
- * It also provides utility methods for access the current JsonWebToken claim values.
- */
-@ApplicationScoped
-public class MPJWTProducer {
- private static Logger log = Logger.getLogger(MPJWTProducer.class.getName());
- private static final String TMP = "tmp";
- private static ThreadLocal<JsonWebToken> currentPrincipal = new ThreadLocal<>();
-
- public static void setJWTPrincipal(JsonWebToken principal) {
- currentPrincipal.set(principal);
- }
-
- public static JsonWebToken getJWTPrincpal() {
- return currentPrincipal.get();
- }
-
- @PostConstruct
- void init() {
- log.fine("MPJWTProducer initialized");
- }
-
- void observeRequestInitialized(@Observes @Initialized(RequestScoped.class) Object event) {
- log.finest(String.format("observeRequestInitialized, event=%s", event));
- }
-
- void observeRequestDestroyed(@Observes @Destroyed(RequestScoped.class) Object event) {
- log.finest(String.format("observeRequestDestroyed, event=%s", event));
- }
-
- /**
- * The @RequestScoped producer method for the current JsonWebToken
- *
- * @return
- */
- @Produces
- @RequestScoped
- JsonWebToken currentPrincipalOrNull() {
- return currentPrincipal.get();
- }
-
- /**
- * A utility method for accessing a claim from the current JsonWebToken as a ClaimValue<Optional<T>> object.
- *
- * @param name - name of the claim
- * @param <T> expected actual type of the claim
- * @return the claim value wrapper object
- */
- static <T> ClaimValue<Optional<T>> generalClaimValueProducer(String name) {
- ClaimValueWrapper<Optional<T>> wrapper = new ClaimValueWrapper<>(name);
- T value = getValue(name, false);
- Optional<T> optValue = Optional.ofNullable(value);
- wrapper.setValue(optValue);
- return wrapper;
- }
-
- /**
- * Return the indicated claim value as a JsonValue
- *
- * @param name - name of the claim
- * @return a JsonValue wrapper
- */
- static JsonValue generalJsonValueProducer(String name) {
- Object value = getValue(name, false);
- JsonValue jsonValue = wrapValue(value);
- return jsonValue;
- }
-
- public static <T> T getValue(String name, boolean isOptional) {
- JsonWebToken jwt = getJWTPrincpal();
- if (jwt == null) {
- log.fine(String.format("getValue(%s), null JsonWebToken", name));
- return null;
- }
-
- Optional<T> claimValue = jwt.claim(name);
- if (!isOptional && !claimValue.isPresent()) {
- log.fine(String.format("Failed to find Claim for: %s", name));
- }
- log.fine(String.format("getValue(%s), isOptional=%s, claimValue=%s", name, isOptional, claimValue));
- return claimValue.orElse(null);
- }
-
- static JsonObject replaceMap(Map<String, Object> map) {
- JsonObjectBuilder builder = Json.createObjectBuilder();
- for (Map.Entry<String, Object> entry : map.entrySet()) {
- Object entryValue = entry.getValue();
- if (entryValue instanceof Map) {
- JsonObject entryJsonObject = replaceMap((Map<String, Object>) entryValue);
- builder.add(entry.getKey(), entryJsonObject);
- } else if (entryValue instanceof List) {
- JsonArray array = (JsonArray) wrapValue(entryValue);
- builder.add(entry.getKey(), array);
- } else if (entryValue instanceof Long || entryValue instanceof Integer) {
- long lvalue = ((Number) entryValue).longValue();
- builder.add(entry.getKey(), lvalue);
- } else if (entryValue instanceof Double || entryValue instanceof Float) {
- double dvalue = ((Number) entryValue).doubleValue();
- builder.add(entry.getKey(), dvalue);
- } else if (entryValue instanceof Boolean) {
- boolean flag = ((Boolean) entryValue).booleanValue();
- builder.add(entry.getKey(), flag);
- } else if (entryValue instanceof String) {
- builder.add(entry.getKey(), entryValue.toString());
- }
- }
- return builder.build();
- }
-
- static JsonValue wrapValue(Object value) {
- JsonValue jsonValue = null;
- if (value instanceof JsonValue) {
- // This may already be a JsonValue
- jsonValue = (JsonValue) value;
- } else if (value instanceof String) {
- jsonValue = Json.createObjectBuilder()
- .add(TMP, value.toString())
- .build()
- .getJsonString(TMP);
- } else if (value instanceof Number) {
- Number number = (Number) value;
- if ((number instanceof Long) || (number instanceof Integer)) {
- jsonValue = Json.createObjectBuilder()
- .add(TMP, number.longValue())
- .build()
- .getJsonNumber(TMP);
- } else {
- jsonValue = Json.createObjectBuilder()
- .add(TMP, number.doubleValue())
- .build()
- .getJsonNumber(TMP);
- }
- } else if (value instanceof Boolean) {
- Boolean flag = (Boolean) value;
- jsonValue = flag ? JsonValue.TRUE : JsonValue.FALSE;
- } else if (value instanceof Collection) {
- JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
- Collection list = (Collection) value;
- for (Object element : list) {
- if (element instanceof String) {
- arrayBuilder.add(element.toString());
- } else {
- JsonValue jvalue = wrapValue(element);
- arrayBuilder.add(jvalue);
- }
- }
- jsonValue = arrayBuilder.build();
- } else if (value instanceof Map) {
- jsonValue = replaceMap((Map) value);
- }
- return jsonValue;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/RawClaimTypeProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/RawClaimTypeProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/RawClaimTypeProducer.java
deleted file mode 100644
index b52912c..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/RawClaimTypeProducer.java
+++ /dev/null
@@ -1,69 +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.tomee.microprofile.jwt;
-
-import org.eclipse.microprofile.jwt.Claim;
-import org.eclipse.microprofile.jwt.ClaimValue;
-import org.eclipse.microprofile.jwt.Claims;
-
-import javax.enterprise.inject.Produces;
-import javax.enterprise.inject.spi.InjectionPoint;
-import javax.inject.Named;
-import java.lang.annotation.Annotation;
-import java.util.Optional;
-import java.util.logging.Logger;
-
-/**
- *
- */
-public class RawClaimTypeProducer {
- private static Logger log = Logger.getLogger(RawClaimTypeProducer.class.getName());
-
- @Produces
- @Claim("")
- @Named("RawClaimTypeProducer#getValue")
- public Object getValue(InjectionPoint ip) {
- log.fine(String.format("getValue(%s)", ip));
- String name = getName(ip);
- ClaimValue<Optional<Object>> cv = MPJWTProducer.generalClaimValueProducer(name);
- Optional<Object> value = cv.getValue();
- Object returnValue = value.orElse(null);
- return returnValue;
- }
-
- @Produces
- @Claim("")
- @Named("RawClaimTypeProducer#getOptionalValue")
- public Optional getOptionalValue(InjectionPoint ip) {
- log.fine(String.format("getOptionalValue(%s)", ip));
- String name = getName(ip);
- ClaimValue<Optional<Object>> cv = MPJWTProducer.generalClaimValueProducer(name);
- Optional<Object> value = cv.getValue();
- return value;
- }
-
- String getName(InjectionPoint ip) {
- String name = null;
- for (Annotation ann : ip.getQualifiers()) {
- if (ann instanceof Claim) {
- Claim claim = (Claim) ann;
- name = claim.standard() == Claims.UNKNOWN ? claim.value() : claim.standard().name();
- }
- }
- return name;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java
index ba57491..0c65795 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java
@@ -16,6 +16,9 @@
*/
package org.apache.tomee.microprofile.jwt;
+import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfo;
+import org.apache.tomee.microprofile.jwt.principal.DefaultJWTCallerPrincipalFactory;
+import org.apache.tomee.microprofile.jwt.principal.JWTCallerPrincipalFactory;
import org.eclipse.microprofile.jwt.JsonWebToken;
import org.eclipse.microprofile.jwt.tck.util.ITokenParser;
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimLiteral.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimLiteral.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimLiteral.java
new file mode 100644
index 0000000..6c07f8c
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimLiteral.java
@@ -0,0 +1,32 @@
+/*
+ * 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.tomee.microprofile.jwt.cdi;
+
+import javax.enterprise.util.AnnotationLiteral;
+
+import org.eclipse.microprofile.jwt.Claim;
+import org.eclipse.microprofile.jwt.Claims;
+
+public class ClaimLiteral extends AnnotationLiteral<Claim> implements Claim {
+ public String value() {
+ return "";
+ }
+
+ public Claims standard() {
+ return Claims.UNKNOWN;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimProviderBeanAttributes.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimProviderBeanAttributes.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimProviderBeanAttributes.java
new file mode 100644
index 0000000..4c446c0
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimProviderBeanAttributes.java
@@ -0,0 +1,83 @@
+/*
+ * 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.tomee.microprofile.jwt.cdi;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Set;
+
+import javax.enterprise.inject.spi.BeanAttributes;
+
+/**
+ * An implementation of BeanAttributes<Object> that wraps the generic producer BeanAttributes
+ * to allow the MPJWTExtension to collect the types of all corresponding injection sites
+ *
+ */
+public class ClaimProviderBeanAttributes implements BeanAttributes<Object> {
+ /**
+ * Decorate the ConfigPropertyProducer BeanAttributes to set the types the producer applies to. This set is collected
+ * from all injection points annotated with @ConfigProperty.
+ *
+ * @param delegate - the original producer method BeanAttributes
+ * @param types - the full set of @Claim injection point types
+ */
+ public ClaimProviderBeanAttributes(BeanAttributes<Object> delegate, Set<Type> types, Set<Annotation> qualifiers) {
+ this.delegate = delegate;
+ this.types = types;
+ this.qualifiers = qualifiers;
+ if (types.size() == 0) {
+ Thread.dumpStack();
+ }
+ }
+
+ @Override
+ public Set<Type> getTypes() {
+ return types;
+ }
+
+ @Override
+ public Set<Annotation> getQualifiers() {
+ return qualifiers;
+ }
+
+ @Override
+ public Class<? extends Annotation> getScope() {
+ return delegate.getScope();
+ }
+
+ @Override
+ public String getName() {
+ return delegate.getName();
+ }
+
+ @Override
+ public Set<Class<? extends Annotation>> getStereotypes() {
+ return delegate.getStereotypes();
+ }
+
+ @Override
+ public boolean isAlternative() {
+ return delegate.isAlternative();
+ }
+
+ private BeanAttributes<Object> delegate;
+
+ private Set<Type> types;
+
+ private Set<Annotation> qualifiers;
+
+}
\ No newline at end of file
[20/38] tomee git commit: some refactoring
Posted by jl...@apache.org.
some refactoring
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/1ad96bbd
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/1ad96bbd
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/1ad96bbd
Branch: refs/heads/master
Commit: 1ad96bbdf1239c4d57cb5b0bc9fa857fa028f427
Parents: 812cfed
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Tue Feb 27 11:03:11 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Tue Feb 27 11:03:11 2018 +0100
----------------------------------------------------------------------
tck/mp-jwt-embedded/pom.xml | 16 ++--
.../apache/tomee/microprofile/jwt/KeyUtils.java | 85 -------------------
.../tomee/microprofile/jwt/MPJWTFilter.java | 2 +-
.../microprofile/jwt/MPJWTInitializer.java | 1 +
.../tomee/microprofile/jwt/ParseException.java | 4 +-
.../tomee/microprofile/jwt/TCKTokenParser.java | 2 +-
.../microprofile/jwt/cdi/ClaimLiteral.java | 32 --------
.../jwt/cdi/ClaimProviderBeanAttributes.java | 23 ++----
.../jwt/cdi/ClaimValueProducer.java | 16 ++--
.../microprofile/jwt/cdi/ClaimValueWrapper.java | 13 ++-
.../microprofile/jwt/cdi/JsonValueProducer.java | 37 ++++-----
.../microprofile/jwt/cdi/JsonbProducer.java | 45 ++++++++++
.../microprofile/jwt/cdi/MPJWTCDIExtension.java | 15 +---
.../microprofile/jwt/cdi/MPJWTProducer.java | 86 +++-----------------
.../jwt/cdi/RawClaimTypeProducer.java | 21 ++---
.../jwt/config/JWTAuthContextInfoProvider.java | 42 +++++-----
.../principal/DefaultJWTCallerPrincipal.java | 6 +-
tck/mp-jwt-embedded/src/test/resources/dev.xml | 6 +-
18 files changed, 148 insertions(+), 304 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/pom.xml
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/pom.xml b/tck/mp-jwt-embedded/pom.xml
index 272f4ad..5055ac4 100644
--- a/tck/mp-jwt-embedded/pom.xml
+++ b/tck/mp-jwt-embedded/pom.xml
@@ -96,15 +96,21 @@
<artifactId>jose4j</artifactId>
<version>0.6.0</version>
</dependency>
+
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-json_1.1_spec</artifactId>
+ <version>1.0</version>
+ </dependency>
<dependency>
- <groupId>javax.json.bind</groupId>
- <artifactId>javax.json.bind-api</artifactId>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-jsonb_1.0_spec</artifactId>
<version>1.0</version>
</dependency>
<dependency>
- <groupId>org.glassfish</groupId>
- <artifactId>javax.json</artifactId>
- <version>1.0.4</version>
+ <groupId>org.apache.johnzon</groupId>
+ <artifactId>johnzon-jsonb</artifactId>
+ <version>1.1.2</version>
</dependency>
</dependencies>
http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/KeyUtils.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/KeyUtils.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/KeyUtils.java
deleted file mode 100644
index c65ea98..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/KeyUtils.java
+++ /dev/null
@@ -1,85 +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.tomee.microprofile.jwt;
-
-import java.io.InputStream;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.Base64;
-
-public class KeyUtils {
- private KeyUtils() {
- }
-
- public static PrivateKey readPrivateKey(String pemResName) throws Exception {
- InputStream contentIS = KeyUtils.class.getResourceAsStream(pemResName);
- byte[] tmp = new byte[4096];
- int length = contentIS.read(tmp);
- PrivateKey privateKey = decodePrivateKey(new String(tmp, 0, length));
- return privateKey;
- }
-
- public static PublicKey readPublicKey(String pemResName) throws Exception {
- InputStream contentIS = KeyUtils.class.getResourceAsStream(pemResName);
- byte[] tmp = new byte[4096];
- int length = contentIS.read(tmp);
- PublicKey publicKey = decodePublicKey(new String(tmp, 0, length));
- return publicKey;
- }
-
- public static KeyPair generateKeyPair(int keySize) throws NoSuchAlgorithmException {
- KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
- keyPairGenerator.initialize(keySize);
- KeyPair keyPair = keyPairGenerator.genKeyPair();
- return keyPair;
- }
-
- public static PrivateKey decodePrivateKey(String pemEncoded) throws Exception {
- pemEncoded = removeBeginEnd(pemEncoded);
- byte[] pkcs8EncodedBytes = Base64.getDecoder().decode(pemEncoded);
-
- // extract the private key
-
- PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pkcs8EncodedBytes);
- KeyFactory kf = KeyFactory.getInstance("RSA");
- PrivateKey privKey = kf.generatePrivate(keySpec);
- return privKey;
- }
-
- public static PublicKey decodePublicKey(String pemEncoded) throws Exception {
- pemEncoded = removeBeginEnd(pemEncoded);
- byte[] encodedBytes = Base64.getDecoder().decode(pemEncoded);
-
- X509EncodedKeySpec spec = new X509EncodedKeySpec(encodedBytes);
- KeyFactory kf = KeyFactory.getInstance("RSA");
- return kf.generatePublic(spec);
- }
-
- private static String removeBeginEnd(String pem) {
- pem = pem.replaceAll("-----BEGIN(.*)KEY-----", "");
- pem = pem.replaceAll("-----END(.*)KEY-----", "");
- pem = pem.replaceAll("\r\n", "");
- pem = pem.replaceAll("\n", "");
- return pem.trim();
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
index 0c80696..752bcda 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
@@ -69,7 +69,7 @@ public class MPJWTFilter implements Filter {
final String token = authorizationHeader.substring("bearer ".length());
final JsonWebToken jsonWebToken;
try {
- jsonWebToken = DefaultJWTCallerPrincipalFactory.instance().parse(token, authContextInfo);
+ jsonWebToken = validate(token);
} catch (final ParseException e) {
// todo properly handle the exception as required per spec
http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
index 8fa9259..28a1735 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
@@ -60,6 +60,7 @@ public class MPJWTInitializer implements ServletContainerInitializer {
MPJWTContext.addMapping(
new MPJWTContext.MPJWTConfigKey(
ctx.getContextPath(),
+ // todo instead of empty path, we need to look for default value
applicationPath == null ? "" : applicationPath.value()),
new MPJWTContext.MPJWTConfigValue(
http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ParseException.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ParseException.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ParseException.java
index 60269b0..d9572d5 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ParseException.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/ParseException.java
@@ -22,11 +22,11 @@ package org.apache.tomee.microprofile.jwt;
public class ParseException extends Exception {
private static final long serialVersionUID = 1L;
- public ParseException(String message) {
+ public ParseException(final String message) {
super(message);
}
- public ParseException(String message, Throwable cause) {
+ public ParseException(final String message, final Throwable cause) {
super(message, cause);
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java
index aeea598..ae563ec 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java
@@ -31,7 +31,7 @@ import java.security.interfaces.RSAPublicKey;
public class TCKTokenParser implements ITokenParser {
@Override
- public JsonWebToken parse(String bearerToken, String issuer, PublicKey publicKey) throws Exception {
+ public JsonWebToken parse(final String bearerToken, final String issuer, final PublicKey publicKey) throws Exception {
final JWTAuthContextInfo authContextInfo = new JWTAuthContextInfo((RSAPublicKey) publicKey, issuer);
final JWTCallerPrincipalFactory factory = DefaultJWTCallerPrincipalFactory.instance();
return factory.parse(bearerToken, authContextInfo);
http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimLiteral.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimLiteral.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimLiteral.java
deleted file mode 100644
index 319f122..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimLiteral.java
+++ /dev/null
@@ -1,32 +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.tomee.microprofile.jwt.cdi;
-
-import org.eclipse.microprofile.jwt.Claim;
-import org.eclipse.microprofile.jwt.Claims;
-
-import javax.enterprise.util.AnnotationLiteral;
-
-public class ClaimLiteral extends AnnotationLiteral<Claim> implements Claim {
- public String value() {
- return "";
- }
-
- public Claims standard() {
- return Claims.UNKNOWN;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimProviderBeanAttributes.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimProviderBeanAttributes.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimProviderBeanAttributes.java
index 88e7724..f15a3fe 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimProviderBeanAttributes.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimProviderBeanAttributes.java
@@ -21,29 +21,16 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Set;
-/**
- * An implementation of BeanAttributes<Object> that wraps the generic producer BeanAttributes
- * to allow the MPJWTExtension to collect the types of all corresponding injection sites
- */
public class ClaimProviderBeanAttributes implements BeanAttributes<Object> {
- private BeanAttributes<Object> delegate;
- private Set<Type> types;
- private Set<Annotation> qualifiers;
- /**
- * Decorate the ConfigPropertyProducer BeanAttributes to set the types the producer applies to. This set is collected
- * from all injection points annotated with @ConfigProperty.
- *
- * @param delegate - the original producer method BeanAttributes
- * @param types - the full set of @Claim injection point types
- */
- public ClaimProviderBeanAttributes(BeanAttributes<Object> delegate, Set<Type> types, Set<Annotation> qualifiers) {
+ private final BeanAttributes<Object> delegate;
+ private final Set<Type> types;
+ private final Set<Annotation> qualifiers;
+
+ public ClaimProviderBeanAttributes(final BeanAttributes<Object> delegate, final Set<Type> types, final Set<Annotation> qualifiers) {
this.delegate = delegate;
this.types = types;
this.qualifiers = qualifiers;
- if (types.size() == 0) {
- Thread.dumpStack();
- }
}
@Override
http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java
index 1881401..aeed7c8 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java
@@ -22,25 +22,25 @@ import org.eclipse.microprofile.jwt.Claims;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
+import javax.inject.Inject;
import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Optional;
-/**
- * A producer for the ClaimValue<T> wrapper injection sites.
- *
- * @param <T> the raw claim type
- */
public class ClaimValueProducer<T> {
+ @Inject
+ private MPJWTProducer producer;
+
@Produces
@Claim("")
- ClaimValue<T> produce(InjectionPoint ip) {
+ ClaimValue<T> produce(final InjectionPoint ip) {
String name = getName(ip);
- ClaimValue<Optional<T>> cv = MPJWTProducer.generalClaimValueProducer(name);
+ ClaimValue<Optional<T>> cv = producer.generalClaimValueProducer(name);
ClaimValue<T> returnValue = (ClaimValue<T>) cv;
Optional<T> value = cv.getValue();
+
// Pull out the ClaimValue<T> T type,
Type matchType = ip.getType();
Type actualType = Object.class;
@@ -62,7 +62,7 @@ public class ClaimValueProducer<T> {
return returnValue;
}
- String getName(InjectionPoint ip) {
+ String getName(final InjectionPoint ip) {
String name = null;
for (Annotation ann : ip.getQualifiers()) {
if (ann instanceof Claim) {
http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java
index 6776191..e0aa68f 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java
@@ -18,14 +18,9 @@ package org.apache.tomee.microprofile.jwt.cdi;
import org.eclipse.microprofile.jwt.ClaimValue;
-/**
- * An implementation of the ClaimValue interface
- *
- * @param <T> the claim value type
- */
public class ClaimValueWrapper<T> implements ClaimValue<T> {
- private String name;
+ private final String name;
private T value;
public ClaimValueWrapper(String name) {
@@ -48,7 +43,9 @@ public class ClaimValueWrapper<T> implements ClaimValue<T> {
@Override
public String toString() {
- return String.format("ClaimValueWrapper[@%s], name=%s, value[%s]=%s", Integer.toHexString(hashCode()),
- name, value.getClass(), value);
+ return "ClaimValueWrapper{" +
+ "name='" + name + '\'' +
+ ", value=" + value +
+ '}';
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonValueProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonValueProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonValueProducer.java
index 2f991b2..af15b89 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonValueProducer.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonValueProducer.java
@@ -21,6 +21,7 @@ import org.eclipse.microprofile.jwt.Claims;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
+import javax.inject.Inject;
import javax.json.JsonArray;
import javax.json.JsonNumber;
import javax.json.JsonObject;
@@ -28,77 +29,73 @@ import javax.json.JsonString;
import javax.json.JsonValue;
import java.lang.annotation.Annotation;
import java.util.Optional;
-import java.util.logging.Logger;
-/**
- * A producer for JsonValue injection types
- */
public class JsonValueProducer {
- private static Logger log = Logger.getLogger(JsonValueProducer.class.getName());
+
+ @Inject
+ private MPJWTProducer producer;
@Produces
@Claim("")
- public JsonString getJsonString(InjectionPoint ip) {
+ public JsonString getJsonString(final InjectionPoint ip) {
return getValue(ip);
}
@Produces
@Claim("")
- public Optional<JsonString> getOptionalJsonString(InjectionPoint ip) {
+ public Optional<JsonString> getOptionalJsonString(final InjectionPoint ip) {
return getOptionalValue(ip);
}
@Produces
@Claim("")
- public JsonNumber getJsonNumber(InjectionPoint ip) {
+ public JsonNumber getJsonNumber(final InjectionPoint ip) {
return getValue(ip);
}
@Produces
@Claim("")
- public Optional<JsonNumber> getOptionalJsonNumber(InjectionPoint ip) {
+ public Optional<JsonNumber> getOptionalJsonNumber(final InjectionPoint ip) {
return getOptionalValue(ip);
}
@Produces
@Claim("")
- public JsonArray getJsonArray(InjectionPoint ip) {
+ public JsonArray getJsonArray(final InjectionPoint ip) {
return getValue(ip);
}
@Produces
@Claim("")
- public Optional<JsonArray> getOptionalJsonArray(InjectionPoint ip) {
+ public Optional<JsonArray> getOptionalJsonArray(final InjectionPoint ip) {
return getOptionalValue(ip);
}
@Produces
@Claim("")
- public JsonObject getJsonObject(InjectionPoint ip) {
+ public JsonObject getJsonObject(final InjectionPoint ip) {
return getValue(ip);
}
@Produces
@Claim("")
- public Optional<JsonObject> getOptionalJsonObject(InjectionPoint ip) {
+ public Optional<JsonObject> getOptionalJsonObject(final InjectionPoint ip) {
return getOptionalValue(ip);
}
- public <T extends JsonValue> T getValue(InjectionPoint ip) {
- log.fine(String.format("JsonValueProducer(%s).produce", ip));
+ public <T extends JsonValue> T getValue(final InjectionPoint ip) {
String name = getName(ip);
- T jsonValue = (T) MPJWTProducer.generalJsonValueProducer(name);
+ T jsonValue = (T) producer.generalJsonValueProducer(name);
return jsonValue;
}
- public <T extends JsonValue> Optional<T> getOptionalValue(InjectionPoint ip) {
- log.fine(String.format("JsonValueProducer(%s).produce", ip));
+ public <T extends JsonValue> Optional<T> getOptionalValue(final InjectionPoint ip) {
String name = getName(ip);
- T jsonValue = (T) MPJWTProducer.generalJsonValueProducer(name);
+ T jsonValue = (T) producer.generalJsonValueProducer(name);
return Optional.ofNullable(jsonValue);
}
- String getName(InjectionPoint ip) {
+ String getName(final InjectionPoint ip) {
String name = null;
for (Annotation ann : ip.getQualifiers()) {
if (ann instanceof Claim) {
http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java
new file mode 100644
index 0000000..7774cbf
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java
@@ -0,0 +1,45 @@
+/*
+ * 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.tomee.microprofile.jwt.cdi;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Disposes;
+import javax.enterprise.inject.Produces;
+import javax.json.bind.Jsonb;
+import javax.json.bind.JsonbBuilder;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+@ApplicationScoped
+public class JsonbProducer {
+
+ private static Logger log = Logger.getLogger(MPJWTCDIExtension.class.getName());
+
+ @Produces
+ public Jsonb jsonb() {
+ return JsonbBuilder.create();
+ }
+
+ public void close(@Disposes final Jsonb jsonb) {
+ try {
+ jsonb.close();
+
+ } catch (final Exception e) {
+ log.log(Level.WARNING, e.getMessage(), e);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
index 3700494..7375d65 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
@@ -48,20 +48,6 @@ import java.util.Optional;
import java.util.Set;
import java.util.logging.Logger;
-/**
- * A CDI extension that provides a producer for the current authenticated JsonWebToken based on a thread
- * local value that is managed by the {@link JWTAuthMechanism} request
- * authentication handler.
- * <p>
- * This also installs the producer methods for the discovered:
- * <ul>
- * <li>@Claim ClaimValue<T> injection sites.</li>
- * <li>@Claim raw type<T> injection sites.</li>
- * <li>@Claim JsonValue injection sites.</li>
- * </ul>
- *
- * @see JWTAuthMechanism
- */
public class MPJWTCDIExtension implements Extension {
private static Logger log = Logger.getLogger(MPJWTCDIExtension.class.getName());
/**
@@ -83,6 +69,7 @@ public class MPJWTCDIExtension implements Extension {
public void observeBeforeBeanDiscovery(@Observes BeforeBeanDiscovery bbd, BeanManager beanManager) {
log.fine("MPJWTExtension(), added JWTPrincipalProducer");
bbd.addAnnotatedType(beanManager.createAnnotatedType(TCKTokenParser.class));
+ bbd.addAnnotatedType(beanManager.createAnnotatedType(JsonbProducer.class));
bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTFilter.class));
bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTInitializer.class));
bbd.addAnnotatedType(beanManager.createAnnotatedType(JWTAuthContextInfoProvider.class));
http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
index 42cc8ac..16876fb 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
@@ -19,33 +19,26 @@ package org.apache.tomee.microprofile.jwt.cdi;
import org.eclipse.microprofile.jwt.ClaimValue;
import org.eclipse.microprofile.jwt.JsonWebToken;
-import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.context.Destroyed;
-import javax.enterprise.context.Initialized;
import javax.enterprise.context.RequestScoped;
-import javax.enterprise.event.Observes;
import javax.enterprise.inject.Produces;
+import javax.inject.Inject;
import javax.json.Json;
-import javax.json.JsonArray;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObject;
-import javax.json.JsonObjectBuilder;
import javax.json.JsonValue;
+import javax.json.bind.Jsonb;
import java.util.Collection;
-import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.logging.Logger;
-/**
- * A class that tracks the current validated MP-JWT and associated JsonWebToken via a thread
- * local to provide a @RequestScoped JsonWebToken producer method.
- * <p>
- * It also provides utility methods for access the current JsonWebToken claim values.
- */
@ApplicationScoped
public class MPJWTProducer {
+
+ @Inject
+ private Jsonb jsonb;
+
private static final String TMP = "tmp";
private static Logger log = Logger.getLogger(MPJWTProducer.class.getName());
private static ThreadLocal<JsonWebToken> currentPrincipal = new ThreadLocal<>();
@@ -58,14 +51,7 @@ public class MPJWTProducer {
return currentPrincipal.get();
}
- /**
- * A utility method for accessing a claim from the current JsonWebToken as a ClaimValue<Optional<T>> object.
- *
- * @param name - name of the claim
- * @param <T> expected actual type of the claim
- * @return the claim value wrapper object
- */
- static <T> ClaimValue<Optional<T>> generalClaimValueProducer(String name) {
+ <T> ClaimValue<Optional<T>> generalClaimValueProducer(String name) {
ClaimValueWrapper<Optional<T>> wrapper = new ClaimValueWrapper<>(name);
T value = getValue(name, false);
Optional<T> optValue = Optional.ofNullable(value);
@@ -73,19 +59,13 @@ public class MPJWTProducer {
return wrapper;
}
- /**
- * Return the indicated claim value as a JsonValue
- *
- * @param name - name of the claim
- * @return a JsonValue wrapper
- */
- static JsonValue generalJsonValueProducer(String name) {
+ JsonValue generalJsonValueProducer(String name) {
Object value = getValue(name, false);
JsonValue jsonValue = wrapValue(value);
return jsonValue;
}
- public static <T> T getValue(String name, boolean isOptional) {
+ public <T> T getValue(String name, boolean isOptional) {
JsonWebToken jwt = getJWTPrincpal();
if (jwt == null) {
log.fine(String.format("getValue(%s), null JsonWebToken", name));
@@ -100,33 +80,11 @@ public class MPJWTProducer {
return claimValue.orElse(null);
}
- static JsonObject replaceMap(Map<String, Object> map) {
- JsonObjectBuilder builder = Json.createObjectBuilder();
- for (Map.Entry<String, Object> entry : map.entrySet()) {
- Object entryValue = entry.getValue();
- if (entryValue instanceof Map) {
- JsonObject entryJsonObject = replaceMap((Map<String, Object>) entryValue);
- builder.add(entry.getKey(), entryJsonObject);
- } else if (entryValue instanceof List) {
- JsonArray array = (JsonArray) wrapValue(entryValue);
- builder.add(entry.getKey(), array);
- } else if (entryValue instanceof Long || entryValue instanceof Integer) {
- long lvalue = ((Number) entryValue).longValue();
- builder.add(entry.getKey(), lvalue);
- } else if (entryValue instanceof Double || entryValue instanceof Float) {
- double dvalue = ((Number) entryValue).doubleValue();
- builder.add(entry.getKey(), dvalue);
- } else if (entryValue instanceof Boolean) {
- boolean flag = ((Boolean) entryValue).booleanValue();
- builder.add(entry.getKey(), flag);
- } else if (entryValue instanceof String) {
- builder.add(entry.getKey(), entryValue.toString());
- }
- }
- return builder.build();
+ JsonObject replaceMap(final Map<String, Object> map) {
+ return jsonb.fromJson(jsonb.toJson(map), JsonObject.class);
}
- static JsonValue wrapValue(Object value) {
+ JsonValue wrapValue(Object value) {
JsonValue jsonValue = null;
if (value instanceof JsonValue) {
// This may already be a JsonValue
@@ -170,27 +128,9 @@ public class MPJWTProducer {
return jsonValue;
}
- @PostConstruct
- void init() {
- log.fine("MPJWTProducer initialized");
- }
-
- void observeRequestInitialized(@Observes @Initialized(RequestScoped.class) Object event) {
- log.finest(String.format("observeRequestInitialized, event=%s", event));
- }
-
- void observeRequestDestroyed(@Observes @Destroyed(RequestScoped.class) Object event) {
- log.finest(String.format("observeRequestDestroyed, event=%s", event));
- }
-
- /**
- * The @RequestScoped producer method for the current JsonWebToken
- *
- * @return
- */
@Produces
@RequestScoped
- JsonWebToken currentPrincipalOrNull() {
+ JsonWebToken currentPrincipal() {
return currentPrincipal.get();
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/RawClaimTypeProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/RawClaimTypeProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/RawClaimTypeProducer.java
index 1ab817e..55b6324 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/RawClaimTypeProducer.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/RawClaimTypeProducer.java
@@ -22,24 +22,22 @@ import org.eclipse.microprofile.jwt.Claims;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
+import javax.inject.Inject;
import javax.inject.Named;
import java.lang.annotation.Annotation;
import java.util.Optional;
-import java.util.logging.Logger;
-/**
- *
- */
public class RawClaimTypeProducer {
- private static Logger log = Logger.getLogger(RawClaimTypeProducer.class.getName());
+
+ @Inject
+ private MPJWTProducer producer;
@Produces
@Claim("")
@Named("RawClaimTypeProducer#getValue")
- public Object getValue(InjectionPoint ip) {
- log.fine(String.format("getValue(%s)", ip));
+ public Object getValue(final InjectionPoint ip) {
String name = getName(ip);
- ClaimValue<Optional<Object>> cv = MPJWTProducer.generalClaimValueProducer(name);
+ ClaimValue<Optional<Object>> cv = producer.generalClaimValueProducer(name);
Optional<Object> value = cv.getValue();
Object returnValue = value.orElse(null);
return returnValue;
@@ -48,15 +46,14 @@ public class RawClaimTypeProducer {
@Produces
@Claim("")
@Named("RawClaimTypeProducer#getOptionalValue")
- public Optional getOptionalValue(InjectionPoint ip) {
- log.fine(String.format("getOptionalValue(%s)", ip));
+ public Optional getOptionalValue(final InjectionPoint ip) {
String name = getName(ip);
- ClaimValue<Optional<Object>> cv = MPJWTProducer.generalClaimValueProducer(name);
+ ClaimValue<Optional<Object>> cv = producer.generalClaimValueProducer(name);
Optional<Object> value = cv.getValue();
return value;
}
- String getName(InjectionPoint ip) {
+ String getName(final InjectionPoint ip) {
String name = null;
for (Annotation ann : ip.getQualifiers()) {
if (ann instanceof Claim) {
http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfoProvider.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfoProvider.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfoProvider.java
index b810fcf..9247e04 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfoProvider.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfoProvider.java
@@ -16,46 +16,46 @@
*/
package org.apache.tomee.microprofile.jwt.config;
-import org.apache.tomee.microprofile.jwt.KeyUtils;
-
import javax.enterprise.context.Dependent;
import javax.enterprise.inject.Produces;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Base64;
import java.util.Optional;
@Dependent
public class JWTAuthContextInfoProvider {
@Produces
- Optional<JWTAuthContextInfo> getOptionalContextInfo() {
+ Optional<JWTAuthContextInfo> getOptionalContextInfo() throws NoSuchAlgorithmException, InvalidKeySpecException {
JWTAuthContextInfo contextInfo = new JWTAuthContextInfo();
// todo use MP Config to load the configuration
contextInfo.setIssuedBy("https://server.example.com");
- RSAPublicKey pk = null;
- try {
- pk = (RSAPublicKey) KeyUtils.decodePublicKey("-----BEGIN RSA PUBLIC KEY-----\n" +
- "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEq\n" +
- "Fyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwR\n" +
- "TYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5e\n" +
- "UF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9\n" +
- "AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYn\n" +
- "sIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9x\n" +
- "nQIDAQAB\n" +
- "-----END RSA PUBLIC KEY-----\n");
-
- } catch (final Exception e) {
- e.printStackTrace();
- // todo better handling
- throw new RuntimeException(e);
- }
+
+ final String pemEncoded = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEq" +
+ "Fyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwR" +
+ "TYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5e" +
+ "UF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9" +
+ "AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYn" +
+ "sIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9x" +
+ "nQIDAQAB";
+ byte[] encodedBytes = Base64.getDecoder().decode(pemEncoded);
+
+ final X509EncodedKeySpec spec = new X509EncodedKeySpec(encodedBytes);
+ final KeyFactory kf = KeyFactory.getInstance("RSA");
+ final RSAPublicKey pk = (RSAPublicKey) kf.generatePublic(spec);
+
contextInfo.setSignerKey(pk);
return Optional.of(contextInfo);
}
@Produces
- JWTAuthContextInfo getContextInfo() {
+ JWTAuthContextInfo getContextInfo() throws InvalidKeySpecException, NoSuchAlgorithmException {
return getOptionalContextInfo().get();
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
index 120058d..47c6ad3 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
@@ -53,7 +53,7 @@ public class DefaultJWTCallerPrincipal extends JWTCallerPrincipal {
* @param jwt - the parsed JWT token representation
* @param name - the extracted unqiue name to use as the principal name; from "upn", "preferred_username" or "sub" claim
*/
- public DefaultJWTCallerPrincipal(String jwt, String type, JwtClaims claimsSet, String name) {
+ public DefaultJWTCallerPrincipal(final String jwt, final String type, final JwtClaims claimsSet, final String name) {
super(name);
this.jwt = jwt;
this.type = type;
@@ -100,7 +100,7 @@ public class DefaultJWTCallerPrincipal extends JWTCallerPrincipal {
}
@Override
- public Object getClaim(String claimName) {
+ public Object getClaim(final String claimName) {
Claims claimType = Claims.UNKNOWN;
Object claim = null;
try {
@@ -138,7 +138,7 @@ public class DefaultJWTCallerPrincipal extends JWTCallerPrincipal {
}
@Override
- public boolean implies(Subject subject) {
+ public boolean implies(final Subject subject) {
return false;
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/1ad96bbd/tck/mp-jwt-embedded/src/test/resources/dev.xml
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/test/resources/dev.xml b/tck/mp-jwt-embedded/src/test/resources/dev.xml
index f6c4fbd..88932f9 100644
--- a/tck/mp-jwt-embedded/src/test/resources/dev.xml
+++ b/tck/mp-jwt-embedded/src/test/resources/dev.xml
@@ -76,9 +76,13 @@
</run>
</groups>
<classes>
+ <!-- OK
+ -->
<class name="org.eclipse.microprofile.jwt.tck.container.ejb.EjbTest" />
- <class name="org.eclipse.microprofile.jwt.tck.container.jacc.SubjectTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.servlet.ServletTest" />
+ <class name="org.eclipse.microprofile.jwt.tck.container.jacc.SubjectTest" />
+ <!-- KO
+ -->
</classes>
</test>
[36/38] tomee git commit: No more needed
Posted by jl...@apache.org.
No more needed
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/04675f5d
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/04675f5d
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/04675f5d
Branch: refs/heads/master
Commit: 04675f5dfb0c3d235c95386baf7cb59208f7a42e
Parents: 7446cbb
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Wed Mar 7 11:35:02 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Wed Mar 7 11:35:02 2018 +0100
----------------------------------------------------------------------
container/openejb-core/pom.xml | 19 --
.../apache/openejb/core/security/JWTUtil.java | 100 -------
.../server/cxf/rs/MPJWTSecurityContextTest.java | 260 -------------------
3 files changed, 379 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/04675f5d/container/openejb-core/pom.xml
----------------------------------------------------------------------
diff --git a/container/openejb-core/pom.xml b/container/openejb-core/pom.xml
index c7feeee..be1e710 100644
--- a/container/openejb-core/pom.xml
+++ b/container/openejb-core/pom.xml
@@ -712,25 +712,6 @@
<scope>provided</scope>
</dependency>
- <dependency>
- <groupId>org.eclipse.microprofile.config</groupId>
- <artifactId>microprofile-config-api</artifactId>
- <version>1.2</version>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.microprofile.jwt</groupId>
- <artifactId>microprofile-jwt-auth-api</artifactId>
- <version>1.1-SNAPSHOT</version>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>com.nimbusds</groupId>
- <artifactId>nimbus-jose-jwt</artifactId>
- <version>5.1</version>
- <scope>compile</scope>
- </dependency>
-
</dependencies>
<profiles>
http://git-wip-us.apache.org/repos/asf/tomee/blob/04675f5d/container/openejb-core/src/test/java/org/apache/openejb/core/security/JWTUtil.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/test/java/org/apache/openejb/core/security/JWTUtil.java b/container/openejb-core/src/test/java/org/apache/openejb/core/security/JWTUtil.java
deleted file mode 100644
index 4ae438f..0000000
--- a/container/openejb-core/src/test/java/org/apache/openejb/core/security/JWTUtil.java
+++ /dev/null
@@ -1,100 +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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.openejb.core.security;
-
-import com.nimbusds.jose.JOSEException;
-import com.nimbusds.jose.JWSAlgorithm;
-import com.nimbusds.jose.JWSHeader;
-import com.nimbusds.jose.JWSSigner;
-import com.nimbusds.jose.crypto.MACSigner;
-import com.nimbusds.jose.crypto.RSASSASigner;
-import com.nimbusds.jwt.JWTClaimsSet;
-import com.nimbusds.jwt.SignedJWT;
-
-import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
-import java.security.Key;
-import java.security.interfaces.RSAPrivateKey;
-import java.time.LocalDate;
-import java.util.Date;
-import java.util.UUID;
-
-import static java.time.ZoneId.systemDefault;
-
-public class JWTUtil {
-
- protected static final String MYSHAREDSECRET = "abcdefghijklmnopqrstuvwxyzabcdef"; // at least 256 bits
-
- private JWTUtil() {
- // prevent direct instantiation
- }
-
- public static String createValidJwtAccessToken(String... scopes) throws Exception {
- final SecretKey key = new SecretKeySpec(MYSHAREDSECRET.getBytes(), "hmac-sha256");
-
- // Prepare JWT with claims set
- final JWTClaimsSet.Builder claimsBuilder = createValidJwtClaimsSet();
-
- if (scopes != null && scopes.length > 0) {
- claimsBuilder.claim("scopes", scopes);
- }
-
- final JWTClaimsSet claimsSet = claimsBuilder.build();
-
- final JWSHeader header = new JWSHeader(JWSAlgorithm.HS256);
-
- return sign(claimsSet, header, key).serialize();
- }
-
- public static SignedJWT sign(final JWTClaimsSet jwtClaimsSet, final JWSHeader jwsHeader, final Key key) throws JOSEException {
- JWSSigner signer = null;
- if (RSAPrivateKey.class.isInstance(key)) {
- signer = new RSASSASigner(RSAPrivateKey.class.cast(key));
-
- } else if (SecretKey.class.isInstance(key)) {
- signer = new MACSigner(SecretKey.class.cast(key).getEncoded());
-
- } else {
- throw new IllegalArgumentException(String.format("Class %s not supported", key.getClass().getName()));
- }
-
- SignedJWT signedJWT = new SignedJWT(
- jwsHeader,
- jwtClaimsSet);
-
- signedJWT.sign(signer);
-
- return signedJWT;
- }
-
- public static JWTClaimsSet.Builder createValidJwtClaimsSet() {
- final LocalDate now = LocalDate.now();
- return new JWTClaimsSet.Builder()
- .expirationTime(new Date(new Date().getTime() + 1800000))
- .issuer("https://apache.org")
- .jwtID(UUID.randomUUID().toString())
- .issueTime(toDate(now))
- .expirationTime(toDate(now.plusDays(30)))
- .notBeforeTime(toDate(now))
- .claim("role", "ruler of the known universe")
- .claim("token-type", "access-token");
- }
-
- public static Date toDate(final LocalDate localDate) {
- return Date.from(localDate.atStartOfDay(systemDefault()).toInstant());
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/04675f5d/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
----------------------------------------------------------------------
diff --git a/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
deleted file mode 100644
index 10a1305..0000000
--- a/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
+++ /dev/null
@@ -1,260 +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.openejb.server.cxf.rs;
-
-import org.apache.cxf.Bus;
-import org.apache.cxf.endpoint.Server;
-import org.apache.cxf.jaxrs.model.ApplicationInfo;
-import org.apache.openejb.jee.WebApp;
-import org.apache.openejb.junit.ApplicationComposer;
-import org.apache.openejb.observer.Observes;
-import org.apache.openejb.server.cxf.rs.event.ServerCreated;
-import org.apache.openejb.server.rest.InternalApplication;
-import org.apache.openejb.testing.Classes;
-import org.apache.openejb.testing.Configuration;
-import org.apache.openejb.testing.EnableServices;
-import org.apache.openejb.testing.Module;
-import org.apache.openejb.testing.RandomPort;
-import org.apache.openejb.testng.PropertiesBuilder;
-import org.eclipse.microprofile.auth.LoginConfig;
-import org.eclipse.microprofile.jwt.JsonWebToken;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import javax.annotation.PostConstruct;
-import javax.enterprise.context.ApplicationScoped;
-import javax.inject.Inject;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.annotation.WebFilter;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
-import javax.ws.rs.ApplicationPath;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.client.ClientBuilder;
-import javax.ws.rs.core.Application;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.SecurityContext;
-import java.io.IOException;
-import java.lang.annotation.Annotation;
-import java.security.Principal;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Properties;
-import java.util.Set;
-import java.util.function.Predicate;
-
-import static org.junit.Assert.assertEquals;
-
-@EnableServices("jax-rs")
-@RunWith(ApplicationComposer.class)
-public class MPJWTSecurityContextTest {
- @RandomPort("http")
- private int port;
-
- @Configuration
- public Properties props() {
- return new PropertiesBuilder()
- .p("observer", "new://Service?class-name=" + Observer.class.getName()) // properly packaged and auto registered
- .build();
- }
-
- @Module
- @Classes(value = {Res.class, RestApplication.class, MPFilter.class, MPContext.class}, cdi = true)
- public WebApp war() {
- return new WebApp()
- .contextRoot("foo");
- }
-
- @Test
- public void check() {
- // todo: close the client (just to stay clean even in tests and avoid to potentially leak)
- assertEquals("true", ClientBuilder.newClient()
- .target("http://127.0.0.1:" + port)
- .path("foo/api/sc")
- .queryParam("role", "therole")
- .request()
- .accept(MediaType.TEXT_PLAIN_TYPE)
- .get(String.class));
-
- assertEquals("false", ClientBuilder.newClient()
- .target("http://127.0.0.1:" + port)
- .path("foo/api/sc")
- .queryParam("role", "another")
- .request()
- .accept(MediaType.TEXT_PLAIN_TYPE)
- .get(String.class));
- }
-
- @LoginConfig(authMethod = "MP-JWT")
- @ApplicationPath("/api")
- public static class RestApplication extends Application {
- // auto discovered
- }
-
- @Path("sc")
- @ApplicationScoped
- public static class Res {
- @GET
- @Produces(MediaType.TEXT_PLAIN)
- public boolean f(@Context final SecurityContext ctx, @QueryParam("role") final String role) {
- return ctx.isUserInRole(role);
- }
- }
-
- // this should go into a proper artifact for MP-JWT and have the property file so it gets discovered automatically
- public static class Observer {
-
- public void obs(@Observes final ServerCreated event) {
- System.out.println("Observer.obs");
- final Server server = event.getServer();
- final Bus bus = (Bus) server.getEndpoint().get("org.apache.cxf.Bus");
- final ApplicationInfo appInfo = (ApplicationInfo) server.getEndpoint().get("javax.ws.rs.core.Application");
- final Application application = InternalApplication.class.isInstance(appInfo.getProvider())
- ? InternalApplication.class.cast(appInfo.getProvider()).getOriginal()
- : appInfo.getProvider();
-
- final LoginConfig annotation = application.getClass().getAnnotation(LoginConfig.class);
- if (annotation != null && "MP-JWT".equals(annotation.authMethod())) {
- // add the ContainerRequestFilter on the fly
- }
- }
- }
-
- // todo: industrialize that but idea is to fill that during startup to let it be usable at runtime
- // note: the bean must be added through an extension in a real impl
- @ApplicationScoped
- public static class MPContext {
- // todo: login config model, not the raw annot
- private Map<String, LoginConfig> configs = new HashMap<>();
-
- @PostConstruct
- private void init() {
- // todo: drop and replace by actual init
- configs.put("/api", new LoginConfig() {
-
- @Override
- public Class<? extends Annotation> annotationType() {
- return LoginConfig.class;
- }
-
- @Override
- public String authMethod() {
- return "MP-JWT";
- }
-
- @Override
- public String realmName() {
- return "";
- }
- });
- }
-
- public Map<String, LoginConfig> getConfigs() {
- return configs;
- }
- }
-
- @WebFilter(asyncSupported = true, urlPatterns = "/*") // addbefore from an initializer
- public static class MPFilter implements Filter {
- @Inject
- private MPContext context;
-
- @Override
- public void init(final FilterConfig filterConfig) throws ServletException {
- // no-op
- }
-
- @Override
- public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
- throws IOException, ServletException {
- final HttpServletRequest httpServletRequest = HttpServletRequest.class.cast(request);
- final String uri = httpServletRequest.getRequestURI().substring(httpServletRequest.getContextPath().length());
-
- // todo: better handling of conflicting app paths?
- final Optional<Map.Entry<String, LoginConfig>> first = context.getConfigs()
- .entrySet()
- .stream()
- .filter(new Predicate<Map.Entry<String, LoginConfig>>() {
- @Override
- public boolean test(final Map.Entry<String, LoginConfig> e) {
- return uri.startsWith(e.getKey());
- }
- })
- .findFirst();
-
- if (first.isPresent()) {
- chain.doFilter(new HttpServletRequestWrapper(httpServletRequest) {
- private final MPPcp pcp = new MPPcp();
-
- @Override
- public Principal getUserPrincipal() {
- return pcp;
- }
-
- @Override
- public boolean isUserInRole(final String role) {
- return pcp.getGroups().contains(role);
- }
- }, response);
-
- } else {
- chain.doFilter(request, response);
-
- }
- }
-
- @Override
- public void destroy() {
- // no-op
- }
- }
-
- // todo
- public static class MPPcp implements JsonWebToken {
-
- @Override
- public String getName() {
- return "mp";
- }
-
- @Override
- public Set<String> getClaimNames() {
- return Collections.singleton("test");
- }
-
- @Override
- public <T> T getClaim(String claimName) {
- return (T) "foo";
- }
-
- @Override
- public Set<String> getGroups() {
- return Collections.singleton("therole");
- }
- }
-}
\ No newline at end of file
[33/38] tomee git commit: Incorporate feedback and cleanup
Posted by jl...@apache.org.
Incorporate feedback and cleanup
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/0340cef2
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/0340cef2
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/0340cef2
Branch: refs/heads/master
Commit: 0340cef2d96a83349c2ad44eae86da27ada23746
Parents: 898c821
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Wed Mar 7 11:26:30 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Wed Mar 7 11:26:30 2018 +0100
----------------------------------------------------------------------
.../tomee/microprofile/jwt/MPJWTFilter.java | 19 +++----
.../microprofile/jwt/MPJWTInitializer.java | 5 +-
.../tomee/microprofile/jwt/cdi/ClaimBean.java | 54 ++++++++++----------
.../jwt/cdi/ClaimInjectionPoint.java | 5 +-
.../microprofile/jwt/cdi/ClaimValueWrapper.java | 2 +-
.../microprofile/jwt/cdi/DefaultLiteral.java | 2 +-
.../microprofile/jwt/cdi/JsonbProducer.java | 2 +-
.../microprofile/jwt/cdi/MPJWTCDIExtension.java | 16 ++----
.../microprofile/jwt/cdi/MPJWTProducer.java | 4 +-
.../jwt/config/JWTAuthContextInfo.java | 8 +--
.../jwt/jaxrs/MPJWPProviderRegistration.java | 4 +-
.../MPJWTSecurityAnnotationsInterceptor.java | 4 +-
...TSecurityAnnotationsInterceptorsFeature.java | 12 ++---
.../principal/DefaultJWTCallerPrincipal.java | 4 ++
.../DefaultJWTCallerPrincipalFactory.java | 18 ++++---
.../jwt/principal/JWTCallerPrincipal.java | 4 +-
.../principal/JWTCallerPrincipalFactory.java | 8 +--
17 files changed, 87 insertions(+), 84 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/0340cef2/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
index 87ab714..25bf828 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
@@ -54,7 +54,7 @@ public class MPJWTFilter implements Filter {
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
- // get configuration
+ // nothing so far
}
@@ -86,7 +86,7 @@ public class MPJWTFilter implements Filter {
@Override
public void destroy() {
-
+ // nothing to do
}
private static Function<HttpServletRequest, JsonWebToken> token(final HttpServletRequest httpServletRequest, final JWTAuthContextInfo authContextInfo) {
@@ -152,15 +152,12 @@ public class MPJWTFilter implements Filter {
// this is so that the MPJWTProducer can find the function and apply it if necessary
request.setAttribute(JsonWebToken.class.getName(), tokenFunction);
- request.setAttribute("javax.security.auth.subject.callable", new Callable<Subject>() {
- @Override
- public Subject call() throws Exception {
- final Set<Principal> principals = new LinkedHashSet<Principal>();
- final JsonWebToken namePrincipal = tokenFunction.apply(request);
- principals.add(namePrincipal);
- principals.addAll(namePrincipal.getGroups().stream().map(role -> (Principal) () -> role).collect(Collectors.toList()));
- return new Subject(true, principals, Collections.emptySet(), Collections.emptySet());
- }
+ request.setAttribute("javax.security.auth.subject.callable", (Callable<Subject>) () -> {
+ final Set<Principal> principals = new LinkedHashSet<>();
+ final JsonWebToken namePrincipal = tokenFunction.apply(request);
+ principals.add(namePrincipal);
+ principals.addAll(namePrincipal.getGroups().stream().map(role -> (Principal) () -> role).collect(Collectors.toList()));
+ return new Subject(true, principals, Collections.emptySet(), Collections.emptySet());
});
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/0340cef2/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
index fb954a5..cede7dc 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
@@ -36,7 +36,7 @@ public class MPJWTInitializer implements ServletContainerInitializer {
public void onStartup(final Set<Class<?>> classes, final ServletContext ctx) throws ServletException {
if (classes == null || classes.isEmpty()) {
- return; // to classes having @LoginConfig on it
+ return; // no classe having @LoginConfig on it
}
for (Class<?> clazz : classes) {
@@ -47,7 +47,8 @@ public class MPJWTInitializer implements ServletContainerInitializer {
}
if (!Application.class.isAssignableFrom(clazz)) {
- continue; // do we really want Application?
+ continue;
+ // do we really want Application?
// See https://github.com/eclipse/microprofile-jwt-auth/issues/70 to clarify this point
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/0340cef2/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
index 5f7852f..6c7a00d 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
@@ -81,12 +81,12 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
}
private Class getRawType(final Type type) {
- if (type instanceof Class) {
- return (Class) type;
+ if (Class.class.isInstance(type)) {
+ return Class.class.cast(type);
- } else if (type instanceof ParameterizedType) {
- final ParameterizedType paramType = (ParameterizedType) type;
- return (Class) paramType.getRawType();
+ } else if (ParameterizedType.class.isInstance(type)) {
+ final ParameterizedType paramType = ParameterizedType.class.cast(type);
+ return Class.class.cast(paramType.getRawType());
}
throw new UnsupportedOperationException("Unsupported type " + type);
@@ -162,17 +162,17 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
logger.finest(String.format("Found Claim injection with name=%s and for %s", key, ip.toString()));
- if (annotated.getBaseType() instanceof ParameterizedType) {
- final ParameterizedType paramType = (ParameterizedType) annotated.getBaseType();
+ if (ParameterizedType.class.isInstance(annotated.getBaseType())) {
+ final ParameterizedType paramType = ParameterizedType.class.cast(annotated.getBaseType());
final Type rawType = paramType.getRawType();
- if (rawType instanceof Class && paramType.getActualTypeArguments().length == 1) {
+ if (Class.class.isInstance(rawType) && paramType.getActualTypeArguments().length == 1) {
final Class<?> rawTypeClass = ((Class<?>) rawType);
// handle Provider<T>
if (rawTypeClass.isAssignableFrom(Provider.class)) {
final Type providerType = paramType.getActualTypeArguments()[0];
- if (providerType instanceof ParameterizedType && isOptional((ParameterizedType) providerType)) {
+ if (ParameterizedType.class.isInstance(providerType) && isOptional(ParameterizedType.class.cast(providerType))) {
return (T) Optional.ofNullable(getClaimValue(key));
}
return getClaimValue(key);
@@ -181,7 +181,7 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
// handle Instance<T>
if (rawTypeClass.isAssignableFrom(Instance.class)) {
final Type instanceType = paramType.getActualTypeArguments()[0];
- if (instanceType instanceof ParameterizedType && isOptional((ParameterizedType) instanceType)) {
+ if (ParameterizedType.class.isInstance(instanceType) && isOptional(ParameterizedType.class.cast(instanceType))) {
return (T) Optional.ofNullable(getClaimValue(key));
}
return getClaimValue(key);
@@ -192,25 +192,25 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
final Type claimValueType = paramType.getActualTypeArguments()[0];
final ClaimValueWrapper claimValueWrapper = new ClaimValueWrapper(key);
- if (claimValueType instanceof ParameterizedType && isOptional((ParameterizedType) claimValueType)) {
+ if (ParameterizedType.class.isInstance(claimValueType) && isOptional(ParameterizedType.class.cast(claimValueType))) {
claimValueWrapper.setValue(() -> {
final T claimValue = getClaimValue(key);
return Optional.ofNullable(claimValue);
});
- } else if (claimValueType instanceof ParameterizedType && isSet((ParameterizedType) claimValueType)) {
+ } else if (ParameterizedType.class.isInstance(claimValueType) && isSet(ParameterizedType.class.cast(claimValueType))) {
claimValueWrapper.setValue(() -> {
final T claimValue = getClaimValue(key);
return claimValue;
});
- } else if (claimValueType instanceof ParameterizedType && isList((ParameterizedType) claimValueType)) {
+ } else if (ParameterizedType.class.isInstance(claimValueType) && isList(ParameterizedType.class.cast(claimValueType))) {
claimValueWrapper.setValue(() -> {
final T claimValue = getClaimValue(key);
return claimValue;
});
- } else if (claimValueType instanceof Class) {
+ } else if (Class.class.isInstance(claimValueType)) {
claimValueWrapper.setValue(() -> {
final T claimValue = getClaimValue(key);
return claimValue;
@@ -278,22 +278,22 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
private static final String TMP = "tmp";
- private JsonValue wrapValue(Object value) {
+ private JsonValue wrapValue(final Object value) {
JsonValue jsonValue = null;
- if (value instanceof JsonValue) {
+ if (JsonValue.class.isInstance(value)) {
// This may already be a JsonValue
- jsonValue = (JsonValue) value;
+ jsonValue = JsonValue.class.cast(value);
- } else if (value instanceof String) {
+ } else if (String.class.isInstance(value)) {
jsonValue = Json.createObjectBuilder()
.add(TMP, value.toString())
.build()
.getJsonString(TMP);
- } else if (value instanceof Number) {
- final Number number = (Number) value;
- if ((number instanceof Long) || (number instanceof Integer)) {
+ } else if (Number.class.isInstance(value)) {
+ final Number number = Number.class.cast(value);
+ if ((Long.class.isInstance(number)) || (Integer.class.isInstance(number))) {
jsonValue = Json.createObjectBuilder()
.add(TMP, number.longValue())
.build()
@@ -306,16 +306,16 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
.getJsonNumber(TMP);
}
- } else if (value instanceof Boolean) {
- final Boolean flag = (Boolean) value;
+ } else if (Boolean.class.isInstance(value)) {
+ final Boolean flag = Boolean.class.cast(value);
jsonValue = flag ? JsonValue.TRUE : JsonValue.FALSE;
- } else if (value instanceof Collection) {
+ } else if (Collection.class.isInstance(value)) {
final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
- final Collection list = (Collection) value;
+ final Collection list = Collection.class.cast(value);
for (Object element : list) {
- if (element instanceof String) {
+ if (String.class.isInstance(element)) {
arrayBuilder.add(element.toString());
} else {
@@ -325,7 +325,7 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
}
jsonValue = arrayBuilder.build();
- } else if (value instanceof Map) {
+ } else if (Map.class.isInstance(value)) {
jsonValue = jsonb.fromJson(jsonb.toJson(value), JsonObject.class);
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/0340cef2/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimInjectionPoint.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimInjectionPoint.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimInjectionPoint.java
index 949e36c..17be756 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimInjectionPoint.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimInjectionPoint.java
@@ -25,10 +25,11 @@ import java.lang.reflect.Type;
import java.util.Collections;
import java.util.Set;
-class ClaimInjectionPoint implements InjectionPoint {
+public class ClaimInjectionPoint implements InjectionPoint {
+
private final Bean bean;
- ClaimInjectionPoint(Bean bean) {
+ public ClaimInjectionPoint(final Bean bean) {
this.bean = bean;
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/0340cef2/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java
index a5a4bb5..2836abd 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java
@@ -47,7 +47,7 @@ public class ClaimValueWrapper<T> implements ClaimValue<T> {
public String toString() {
return "ClaimValueWrapper{" +
"name='" + name + '\'' +
- ", value=" + value +
+ ", value=" + value.get() +
'}';
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/0340cef2/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/DefaultLiteral.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/DefaultLiteral.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/DefaultLiteral.java
index a084ea3..273ff96 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/DefaultLiteral.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/DefaultLiteral.java
@@ -19,6 +19,6 @@ package org.apache.tomee.microprofile.jwt.cdi;
import javax.enterprise.inject.Default;
import javax.enterprise.util.AnnotationLiteral;
-class DefaultLiteral extends AnnotationLiteral<Default> implements Default {
+public class DefaultLiteral extends AnnotationLiteral<Default> implements Default {
public static final Default INSTANCE = new DefaultLiteral();
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/0340cef2/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java
index a0434ef..59f42c5 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java
@@ -28,7 +28,7 @@ import java.util.logging.Logger;
// todo add a qualifier here so we isolate our instance from what applications would do
public class JsonbProducer {
- private static Logger log = Logger.getLogger(MPJWTCDIExtension.class.getName());
+ private static final Logger log = Logger.getLogger(MPJWTCDIExtension.class.getName());
@Produces
public Jsonb create() {
http://git-wip-us.apache.org/repos/asf/tomee/blob/0340cef2/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
index 05b08de..d1019ee 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
@@ -25,7 +25,6 @@ import org.eclipse.microprofile.jwt.Claim;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.Instance;
import javax.enterprise.inject.spi.AfterBeanDiscovery;
-import javax.enterprise.inject.spi.AfterDeploymentValidation;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.BeforeBeanDiscovery;
import javax.enterprise.inject.spi.Extension;
@@ -39,15 +38,12 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
-import java.util.logging.Logger;
import java.util.stream.Collectors;
public class MPJWTCDIExtension implements Extension {
- private static Logger logger = Logger.getLogger(MPJWTCDIExtension.class.getName());
-
- private static final Predicate<InjectionPoint> NOT_PROVIDERS = ip -> (ip.getType() instanceof Class) || (ip.getType() instanceof ParameterizedType && ((ParameterizedType)ip.getType()).getRawType() != Provider.class);
- private static final Predicate<InjectionPoint> NOT_INSTANCES = ip -> (ip.getType() instanceof Class) || (ip.getType() instanceof ParameterizedType && ((ParameterizedType)ip.getType()).getRawType() != Instance.class);
+ private static final Predicate<InjectionPoint> NOT_PROVIDERS = ip -> (Class.class.isInstance(ip.getType())) || (ParameterizedType.class.isInstance(ip.getType()) && ((ParameterizedType) ip.getType()).getRawType() != Provider.class);
+ private static final Predicate<InjectionPoint> NOT_INSTANCES = ip -> (Class.class.isInstance(ip.getType())) || (ParameterizedType.class.isInstance(ip.getType()) && ((ParameterizedType) ip.getType()).getRawType() != Instance.class);
private static final Map<Type, Type> REPLACED_TYPES = new HashMap<>();
static {
@@ -76,12 +72,12 @@ public class MPJWTCDIExtension implements Extension {
final Set<Type> providerTypes = injectionPoints.stream()
.filter(NOT_PROVIDERS.negate())
- .map(ip -> ((ParameterizedType)ip.getType()).getActualTypeArguments()[0])
+ .map(ip -> ((ParameterizedType) ip.getType()).getActualTypeArguments()[0])
.collect(Collectors.toSet());
final Set<Type> instanceTypes = injectionPoints.stream()
.filter(NOT_INSTANCES.negate())
- .map(ip -> ((ParameterizedType)ip.getType()).getActualTypeArguments()[0])
+ .map(ip -> ((ParameterizedType) ip.getType()).getActualTypeArguments()[0])
.collect(Collectors.toSet());
types.addAll(providerTypes);
@@ -92,10 +88,6 @@ public class MPJWTCDIExtension implements Extension {
.forEach(abd::addBean);
}
- public void validate(@Observes final AfterDeploymentValidation add) {
- // not sure yet if we can eagerly check
- }
-
public void observeBeforeBeanDiscovery(@Observes final BeforeBeanDiscovery bbd, final BeanManager beanManager) {
bbd.addAnnotatedType(beanManager.createAnnotatedType(TCKTokenParser.class));
bbd.addAnnotatedType(beanManager.createAnnotatedType(JsonbProducer.class));
http://git-wip-us.apache.org/repos/asf/tomee/blob/0340cef2/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
index 453dcff..42034b9 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
@@ -37,10 +37,10 @@ public class MPJWTProducer {
public JsonWebToken currentPrincipal() {
Objects.requireNonNull(httpServletRequest, "HTTP Servlet Request is required to produce a JSonWebToken principal.");
- // not very beatiful, but avoids having the MPJWTFilter setting the request or the principal in a thread local
+ // not very beautiful, but avoids having the MPJWTFilter setting the request or the principal in a thread local
// CDI integration already has one - dunno which approach is the best for now
final Object tokenAttribute = httpServletRequest.getAttribute(JsonWebToken.class.getName());
- if (tokenAttribute != null && Function.class.isInstance(tokenAttribute)) {
+ if (Function.class.isInstance(tokenAttribute)) {
return (JsonWebToken) Function.class.cast(tokenAttribute).apply(httpServletRequest);
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/0340cef2/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfo.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfo.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfo.java
index dad5f4d..a969515 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfo.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfo.java
@@ -35,7 +35,7 @@ public class JWTAuthContextInfo {
this.issuedBy = issuedBy;
}
- public JWTAuthContextInfo(JWTAuthContextInfo orig) {
+ public JWTAuthContextInfo(final JWTAuthContextInfo orig) {
this.signerKey = orig.signerKey;
this.issuedBy = orig.issuedBy;
this.expGracePeriodSecs = orig.expGracePeriodSecs;
@@ -45,7 +45,7 @@ public class JWTAuthContextInfo {
return signerKey;
}
- public void setSignerKey(RSAPublicKey signerKey) {
+ public void setSignerKey(final RSAPublicKey signerKey) {
this.signerKey = signerKey;
}
@@ -53,7 +53,7 @@ public class JWTAuthContextInfo {
return issuedBy;
}
- public void setIssuedBy(String issuedBy) {
+ public void setIssuedBy(final String issuedBy) {
this.issuedBy = issuedBy;
}
@@ -61,7 +61,7 @@ public class JWTAuthContextInfo {
return expGracePeriodSecs;
}
- public void setExpGracePeriodSecs(int expGracePeriodSecs) {
+ public void setExpGracePeriodSecs(final int expGracePeriodSecs) {
this.expGracePeriodSecs = expGracePeriodSecs;
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/0340cef2/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWPProviderRegistration.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWPProviderRegistration.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWPProviderRegistration.java
index 2102c89..34f152f 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWPProviderRegistration.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWPProviderRegistration.java
@@ -24,11 +24,11 @@ import org.apache.tomee.microprofile.jwt.MPJWTFilter;
* OpenEJB/TomEE hack to register a new provider on the fly
* Could be package in tomee only or done in another way
*
- * As soon as Roberto is done with the packaging, we can remove all this
+ * As soon as Roberto is done with the packaging, we can remove all this and providers are going to be scanned automatically
*/
public class MPJWPProviderRegistration {
- public void registerProvider(@Observes final ExtensionProviderRegistration event) { // openejb hack to register the provider
+ public void registerProvider(@Observes final ExtensionProviderRegistration event) {
event.getProviders().add(new MPJWTFilter.MPJWTExceptionMapper());
event.getProviders().add(new MPJWTSecurityAnnotationsInterceptorsFeature());
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/0340cef2/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptor.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptor.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptor.java
index e6ccd5a..f604e6b 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptor.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptor.java
@@ -18,7 +18,9 @@ public class MPJWTSecurityAnnotationsInterceptor implements ContainerRequestFilt
private final Set<Method> permitAll;
public MPJWTSecurityAnnotationsInterceptor(final javax.ws.rs.container.ResourceInfo resourceInfo,
- final ConcurrentMap<Method, Set<String>> rolesAllowed, final Set<Method> denyAll, final Set<Method> permitAll) {
+ final ConcurrentMap<Method, Set<String>> rolesAllowed,
+ final Set<Method> denyAll,
+ final Set<Method> permitAll) {
this.resourceInfo = resourceInfo;
this.rolesAllowed = rolesAllowed;
this.denyAll = denyAll;
http://git-wip-us.apache.org/repos/asf/tomee/blob/0340cef2/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptorsFeature.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptorsFeature.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptorsFeature.java
index 5a0a00a..58b3203 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptorsFeature.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptorsFeature.java
@@ -45,7 +45,7 @@ public class MPJWTSecurityAnnotationsInterceptorsFeature implements DynamicFeatu
final boolean hasSecurity = processSecurityAnnotations(resourceInfo.getResourceClass(), resourceInfo.getResourceMethod());
- if (hasSecurity) {
+ if (hasSecurity) { // no need to add interceptor on the resources that don(t have any security requirements to enforce
context.register(new MPJWTSecurityAnnotationsInterceptor(resourceInfo, rolesAllowed, denyAll, permitAll));
}
@@ -67,11 +67,11 @@ public class MPJWTSecurityAnnotationsInterceptorsFeature implements DynamicFeatu
* Process annotations at the class level
*/
if (classSecurityAnnotations.size() > 1) {
- // todo error to properly handle
+ throw new IllegalStateException(clazz.getName() + " has more than one security annotation (RolesAllowed, PermitAll, DenyAll).");
}
if (methodSecurityAnnotations.size() > 1) {
- // todo proper error handling
+ throw new IllegalStateException(method.toString() + " has more than one security annotation (RolesAllowed, PermitAll, DenyAll).");
}
if (methodSecurityAnnotations.size() == 0) { // no need to deal with class level annotations if the method has some
@@ -97,9 +97,9 @@ public class MPJWTSecurityAnnotationsInterceptorsFeature implements DynamicFeatu
}
}
- final RolesAllowed mthdRolesAllowed = (RolesAllowed) method.getAnnotation(RolesAllowed.class);
- final PermitAll mthdPermitAll = (PermitAll) method.getAnnotation(PermitAll.class);
- final DenyAll mthdDenyAll = (DenyAll) method.getAnnotation(DenyAll.class);
+ final RolesAllowed mthdRolesAllowed = method.getAnnotation(RolesAllowed.class);
+ final PermitAll mthdPermitAll = method.getAnnotation(PermitAll.class);
+ final DenyAll mthdDenyAll = method.getAnnotation(DenyAll.class);
if (mthdRolesAllowed != null) {
Set<String> roles = new HashSet<String>();
http://git-wip-us.apache.org/repos/asf/tomee/blob/0340cef2/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
index b0d6a42..661fbde 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
@@ -102,6 +102,10 @@ public class DefaultJWTCallerPrincipal extends JWTCallerPrincipal {
return new HashSet<>(claimsSet.getClaimNames());
}
+ public String getRawToken() {
+ return jwt;
+ }
+
@Override
public Object getClaim(final String claimName) {
Claims claimType = Claims.UNKNOWN;
http://git-wip-us.apache.org/repos/asf/tomee/blob/0340cef2/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipalFactory.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipalFactory.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipalFactory.java
index 5bcaeed..feb2008 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipalFactory.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipalFactory.java
@@ -42,10 +42,10 @@ public class DefaultJWTCallerPrincipalFactory extends JWTCallerPrincipalFactory
@Override
public JWTCallerPrincipal parse(final String token, final JWTAuthContextInfo authContextInfo) throws ParseException {
- JWTCallerPrincipal principal = null;
+ JWTCallerPrincipal principal;
try {
- JwtConsumerBuilder builder = new JwtConsumerBuilder()
+ final JwtConsumerBuilder builder = new JwtConsumerBuilder()
.setRequireExpirationTime()
.setRequireSubject()
.setSkipDefaultAudienceValidation()
@@ -54,15 +54,17 @@ public class DefaultJWTCallerPrincipalFactory extends JWTCallerPrincipalFactory
.setJwsAlgorithmConstraints(
new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.WHITELIST,
AlgorithmIdentifiers.RSA_USING_SHA256));
+
if (authContextInfo.getExpGracePeriodSecs() > 0) {
builder.setAllowedClockSkewInSeconds(authContextInfo.getExpGracePeriodSecs());
+
} else {
builder.setEvaluationTime(NumericDate.fromSeconds(0));
}
- JwtConsumer jwtConsumer = builder.build();
- JwtContext jwtContext = jwtConsumer.process(token);
- String type = jwtContext.getJoseObjects().get(0).getHeader("typ");
+ final JwtConsumer jwtConsumer = builder.build();
+ final JwtContext jwtContext = jwtConsumer.process(token);
+ final String type = jwtContext.getJoseObjects().get(0).getHeader("typ");
// Validate the JWT and process it to the Claims
jwtConsumer.processContext(jwtContext);
JwtClaims claimsSet = jwtContext.getJwtClaims();
@@ -77,9 +79,11 @@ public class DefaultJWTCallerPrincipalFactory extends JWTCallerPrincipalFactory
}
claimsSet.setClaim(Claims.raw_token.name(), token);
principal = new DefaultJWTCallerPrincipal(token, type, claimsSet, principalName);
- } catch (InvalidJwtException e) {
+
+ } catch (final InvalidJwtException e) {
throw new ParseException("Failed to verify token", e);
- } catch (MalformedClaimException e) {
+
+ } catch (final MalformedClaimException e) {
throw new ParseException("Failed to verify token claims", e);
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/0340cef2/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipal.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipal.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipal.java
index 26d9406..d8e3c4c 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipal.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipal.java
@@ -34,7 +34,7 @@ public abstract class JWTCallerPrincipal implements JsonWebToken {
*
* @param name - caller's name
*/
- public JWTCallerPrincipal(String name) {
+ public JWTCallerPrincipal(final String name) {
this.name = name;
}
@@ -50,7 +50,7 @@ public abstract class JWTCallerPrincipal implements JsonWebToken {
* JsonWebToken interface be displayed.
* @return human readable presentation of the caller principal and associated JWT.
*/
- public abstract String toString(boolean showAll);
+ public abstract String toString(final boolean showAll);
public <T> Optional<T> claim(final String claimName) {
final T claim = (T) getClaim(claimName);
http://git-wip-us.apache.org/repos/asf/tomee/blob/0340cef2/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipalFactory.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipalFactory.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipalFactory.java
index 51ca256..e7ebcd6 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipalFactory.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipalFactory.java
@@ -28,6 +28,7 @@ import java.util.ServiceLoader;
* The factory class that provides the token string to JWTCallerPrincipal parsing for a given implementation.
*/
public abstract class JWTCallerPrincipalFactory {
+
private static JWTCallerPrincipalFactory instance;
/**
@@ -100,7 +101,8 @@ public abstract class JWTCallerPrincipalFactory {
instance = spi;
}
}
- } catch (Throwable e) {
+
+ } catch (final Throwable e) {
System.err.printf("Warning: %s\n", e.getMessage());
}
}
@@ -112,7 +114,7 @@ public abstract class JWTCallerPrincipalFactory {
*
* @param resolver the instance to use.
*/
- public static void setInstance(JWTCallerPrincipalFactory resolver) {
+ public static void setInstance(final JWTCallerPrincipalFactory resolver) {
instance = resolver;
}
@@ -123,5 +125,5 @@ public abstract class JWTCallerPrincipalFactory {
* @return A JWTCallerPrincipal representation for the token.
* @throws ParseException on parse or verification failure.
*/
- public abstract JWTCallerPrincipal parse(String token, JWTAuthContextInfo authContextInfo) throws ParseException;
+ public abstract JWTCallerPrincipal parse(final String token, final JWTAuthContextInfo authContextInfo) throws ParseException;
}
\ No newline at end of file
[19/38] tomee git commit: Formating
Posted by jl...@apache.org.
Formating
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/812cfed9
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/812cfed9
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/812cfed9
Branch: refs/heads/master
Commit: 812cfed9bc64f6d5985d507dd00b62cbfa5215bc
Parents: c5964e0
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Tue Feb 27 10:23:02 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Tue Feb 27 10:23:02 2018 +0100
----------------------------------------------------------------------
.../apache/tomee/microprofile/jwt/KeyUtils.java | 5 +-
.../tomee/microprofile/jwt/MPJWTContext.java | 1 -
.../microprofile/jwt/MPJWTInitializer.java | 1 -
.../tomee/microprofile/jwt/TCKTokenParser.java | 4 +-
.../microprofile/jwt/cdi/ClaimLiteral.java | 4 +-
.../jwt/cdi/ClaimProviderBeanAttributes.java | 14 ++--
.../jwt/cdi/ClaimValueProducer.java | 14 ++--
.../microprofile/jwt/cdi/MPJWTCDIExtension.java | 88 ++++++++------------
.../microprofile/jwt/cdi/MPJWTProducer.java | 50 +++++------
.../jwt/config/JWTAuthContextInfo.java | 3 +-
.../DefaultJWTCallerPrincipalFactory.java | 2 +-
.../principal/JWTCallerPrincipalFactory.java | 2 +-
12 files changed, 85 insertions(+), 103 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/812cfed9/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/KeyUtils.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/KeyUtils.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/KeyUtils.java
index 07e00f2..c65ea98 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/KeyUtils.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/KeyUtils.java
@@ -28,6 +28,9 @@ import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class KeyUtils {
+ private KeyUtils() {
+ }
+
public static PrivateKey readPrivateKey(String pemResName) throws Exception {
InputStream contentIS = KeyUtils.class.getResourceAsStream(pemResName);
byte[] tmp = new byte[4096];
@@ -79,6 +82,4 @@ public class KeyUtils {
pem = pem.replaceAll("\n", "");
return pem.trim();
}
- private KeyUtils() {
- }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/812cfed9/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTContext.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTContext.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTContext.java
index 07dfe0b..50b7d1e 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTContext.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTContext.java
@@ -16,7 +16,6 @@
*/
package org.apache.tomee.microprofile.jwt;
-import javax.enterprise.context.ApplicationScoped;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
http://git-wip-us.apache.org/repos/asf/tomee/blob/812cfed9/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
index bb8bb16..8fa9259 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
@@ -18,7 +18,6 @@ package org.apache.tomee.microprofile.jwt;
import org.eclipse.microprofile.auth.LoginConfig;
-import javax.inject.Inject;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
http://git-wip-us.apache.org/repos/asf/tomee/blob/812cfed9/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java
index 0c65795..aeea598 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java
@@ -32,8 +32,8 @@ public class TCKTokenParser implements ITokenParser {
@Override
public JsonWebToken parse(String bearerToken, String issuer, PublicKey publicKey) throws Exception {
- JWTAuthContextInfo authContextInfo = new JWTAuthContextInfo((RSAPublicKey) publicKey, issuer);
- JWTCallerPrincipalFactory factory = DefaultJWTCallerPrincipalFactory.instance();
+ final JWTAuthContextInfo authContextInfo = new JWTAuthContextInfo((RSAPublicKey) publicKey, issuer);
+ final JWTCallerPrincipalFactory factory = DefaultJWTCallerPrincipalFactory.instance();
return factory.parse(bearerToken, authContextInfo);
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/812cfed9/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimLiteral.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimLiteral.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimLiteral.java
index 6c07f8c..319f122 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimLiteral.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimLiteral.java
@@ -16,11 +16,11 @@
*/
package org.apache.tomee.microprofile.jwt.cdi;
-import javax.enterprise.util.AnnotationLiteral;
-
import org.eclipse.microprofile.jwt.Claim;
import org.eclipse.microprofile.jwt.Claims;
+import javax.enterprise.util.AnnotationLiteral;
+
public class ClaimLiteral extends AnnotationLiteral<Claim> implements Claim {
public String value() {
return "";
http://git-wip-us.apache.org/repos/asf/tomee/blob/812cfed9/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimProviderBeanAttributes.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimProviderBeanAttributes.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimProviderBeanAttributes.java
index 4c446c0..88e7724 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimProviderBeanAttributes.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimProviderBeanAttributes.java
@@ -16,18 +16,20 @@
*/
package org.apache.tomee.microprofile.jwt.cdi;
+import javax.enterprise.inject.spi.BeanAttributes;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Set;
-import javax.enterprise.inject.spi.BeanAttributes;
-
/**
* An implementation of BeanAttributes<Object> that wraps the generic producer BeanAttributes
* to allow the MPJWTExtension to collect the types of all corresponding injection sites
- *
*/
public class ClaimProviderBeanAttributes implements BeanAttributes<Object> {
+ private BeanAttributes<Object> delegate;
+ private Set<Type> types;
+ private Set<Annotation> qualifiers;
+
/**
* Decorate the ConfigPropertyProducer BeanAttributes to set the types the producer applies to. This set is collected
* from all injection points annotated with @ConfigProperty.
@@ -74,10 +76,4 @@ public class ClaimProviderBeanAttributes implements BeanAttributes<Object> {
return delegate.isAlternative();
}
- private BeanAttributes<Object> delegate;
-
- private Set<Type> types;
-
- private Set<Annotation> qualifiers;
-
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/812cfed9/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java
index d69df02..1881401 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java
@@ -16,20 +16,20 @@
*/
package org.apache.tomee.microprofile.jwt.cdi;
+import org.eclipse.microprofile.jwt.Claim;
+import org.eclipse.microprofile.jwt.ClaimValue;
+import org.eclipse.microprofile.jwt.Claims;
+
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.spi.InjectionPoint;
import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Optional;
-import javax.enterprise.inject.Produces;
-import javax.enterprise.inject.spi.InjectionPoint;
-
-import org.eclipse.microprofile.jwt.Claim;
-import org.eclipse.microprofile.jwt.ClaimValue;
-import org.eclipse.microprofile.jwt.Claims;
-
/**
* A producer for the ClaimValue<T> wrapper injection sites.
+ *
* @param <T> the raw claim type
*/
public class ClaimValueProducer<T> {
http://git-wip-us.apache.org/repos/asf/tomee/blob/812cfed9/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
index 95e1aea..3700494 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
@@ -16,10 +16,10 @@
*/
package org.apache.tomee.microprofile.jwt.cdi;
-import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfoProvider;
import org.apache.tomee.microprofile.jwt.MPJWTFilter;
import org.apache.tomee.microprofile.jwt.MPJWTInitializer;
import org.apache.tomee.microprofile.jwt.TCKTokenParser;
+import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfoProvider;
import org.eclipse.microprofile.jwt.Claim;
import org.eclipse.microprofile.jwt.Claims;
@@ -64,6 +64,15 @@ import java.util.logging.Logger;
*/
public class MPJWTCDIExtension implements Extension {
private static Logger log = Logger.getLogger(MPJWTCDIExtension.class.getName());
+ /**
+ * A map of claim,type pairs to the injection site information
+ */
+ private HashMap<ClaimIPType, ClaimIP> claims = new HashMap<>();
+ private Set<Type> providerOptionalTypes = new HashSet<>();
+ private Set<Type> providerTypes = new HashSet<>();
+ private Set<Type> rawTypes = new HashSet<>();
+ private Set<Annotation> rawTypeQualifiers = new HashSet<>();
+ private Set<Annotation> providerQualifiers = new HashSet<>();
/**
* Register the MPJWTProducer JsonWebToken producer bean
@@ -243,24 +252,12 @@ public class MPJWTCDIExtension implements Extension {
}
/**
- * A map of claim,type pairs to the injection site information
- */
- private HashMap<ClaimIPType, ClaimIP> claims = new HashMap<>();
-
- private Set<Type> providerOptionalTypes = new HashSet<>();
-
- private Set<Type> providerTypes = new HashSet<>();
-
- private Set<Type> rawTypes = new HashSet<>();
-
- private Set<Annotation> rawTypeQualifiers = new HashSet<>();
-
- private Set<Annotation> providerQualifiers = new HashSet<>();
-
- /**
* A key for a claim,injection site type pair
*/
public static class ClaimIPType implements Comparable<ClaimIPType> {
+ private String claimName;
+ private Type ipType;
+
public ClaimIPType(String claimName, Type ipType) {
this.claimName = claimName;
this.ipType = ipType;
@@ -280,10 +277,6 @@ public class MPJWTCDIExtension implements Extension {
}
return compareTo;
}
-
- private String claimName;
-
- private Type ipType;
}
/**
@@ -291,6 +284,30 @@ public class MPJWTCDIExtension implements Extension {
*/
public static class ClaimIP {
/**
+ * The injection site value type
+ */
+ private Type matchType;
+ /**
+ * The actual type of of the ParameterizedType matchType
+ */
+ private Type valueType;
+ /**
+ * Is valueType actually wrapped in an Optional
+ */
+ private boolean isOptional;
+ private boolean isProviderSite;
+ private boolean isNonStandard;
+ private boolean isJsonValue;
+ /**
+ * The injection site @Claim annotation value
+ */
+ private Claim claim;
+ /**
+ * The location that share the @Claim/type combination
+ */
+ private HashSet<InjectionPoint> injectionPoints = new HashSet<>();
+
+ /**
* Create a ClaimIP from the injection site information
*
* @param matchType - the outer type of the injection site
@@ -360,36 +377,5 @@ public class MPJWTCDIExtension implements Extension {
", ips=" + injectionPoints +
'}';
}
-
- /**
- * The injection site value type
- */
- private Type matchType;
-
- /**
- * The actual type of of the ParameterizedType matchType
- */
- private Type valueType;
-
- /**
- * Is valueType actually wrapped in an Optional
- */
- private boolean isOptional;
-
- private boolean isProviderSite;
-
- private boolean isNonStandard;
-
- private boolean isJsonValue;
-
- /**
- * The injection site @Claim annotation value
- */
- private Claim claim;
-
- /**
- * The location that share the @Claim/type combination
- */
- private HashSet<InjectionPoint> injectionPoints = new HashSet<>();
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/812cfed9/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
index f267437..42cc8ac 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
@@ -46,8 +46,8 @@ import java.util.logging.Logger;
*/
@ApplicationScoped
public class MPJWTProducer {
- private static Logger log = Logger.getLogger(MPJWTProducer.class.getName());
private static final String TMP = "tmp";
+ private static Logger log = Logger.getLogger(MPJWTProducer.class.getName());
private static ThreadLocal<JsonWebToken> currentPrincipal = new ThreadLocal<>();
public static void setJWTPrincipal(JsonWebToken principal) {
@@ -58,30 +58,6 @@ public class MPJWTProducer {
return currentPrincipal.get();
}
- @PostConstruct
- void init() {
- log.fine("MPJWTProducer initialized");
- }
-
- void observeRequestInitialized(@Observes @Initialized(RequestScoped.class) Object event) {
- log.finest(String.format("observeRequestInitialized, event=%s", event));
- }
-
- void observeRequestDestroyed(@Observes @Destroyed(RequestScoped.class) Object event) {
- log.finest(String.format("observeRequestDestroyed, event=%s", event));
- }
-
- /**
- * The @RequestScoped producer method for the current JsonWebToken
- *
- * @return
- */
- @Produces
- @RequestScoped
- JsonWebToken currentPrincipalOrNull() {
- return currentPrincipal.get();
- }
-
/**
* A utility method for accessing a claim from the current JsonWebToken as a ClaimValue<Optional<T>> object.
*
@@ -193,4 +169,28 @@ public class MPJWTProducer {
}
return jsonValue;
}
+
+ @PostConstruct
+ void init() {
+ log.fine("MPJWTProducer initialized");
+ }
+
+ void observeRequestInitialized(@Observes @Initialized(RequestScoped.class) Object event) {
+ log.finest(String.format("observeRequestInitialized, event=%s", event));
+ }
+
+ void observeRequestDestroyed(@Observes @Destroyed(RequestScoped.class) Object event) {
+ log.finest(String.format("observeRequestDestroyed, event=%s", event));
+ }
+
+ /**
+ * The @RequestScoped producer method for the current JsonWebToken
+ *
+ * @return
+ */
+ @Produces
+ @RequestScoped
+ JsonWebToken currentPrincipalOrNull() {
+ return currentPrincipal.get();
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/812cfed9/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfo.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfo.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfo.java
index ef8c0b0..dad5f4d 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfo.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfo.java
@@ -22,6 +22,7 @@ import java.security.interfaces.RSAPublicKey;
* The public key and expected issuer needed to validate a token.
*/
public class JWTAuthContextInfo {
+
private RSAPublicKey signerKey;
private String issuedBy;
private int expGracePeriodSecs = 60;
@@ -29,7 +30,7 @@ public class JWTAuthContextInfo {
public JWTAuthContextInfo() {
}
- public JWTAuthContextInfo(RSAPublicKey signerKey, String issuedBy) {
+ public JWTAuthContextInfo(final RSAPublicKey signerKey, final String issuedBy) {
this.signerKey = signerKey;
this.issuedBy = issuedBy;
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/812cfed9/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipalFactory.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipalFactory.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipalFactory.java
index a420dde..5bcaeed 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipalFactory.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipalFactory.java
@@ -16,8 +16,8 @@
*/
package org.apache.tomee.microprofile.jwt.principal;
-import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfo;
import org.apache.tomee.microprofile.jwt.ParseException;
+import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfo;
import org.eclipse.microprofile.jwt.Claims;
import org.jose4j.jwa.AlgorithmConstraints;
import org.jose4j.jws.AlgorithmIdentifiers;
http://git-wip-us.apache.org/repos/asf/tomee/blob/812cfed9/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipalFactory.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipalFactory.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipalFactory.java
index 3aec7f0..51ca256 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipalFactory.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipalFactory.java
@@ -16,8 +16,8 @@
*/
package org.apache.tomee.microprofile.jwt.principal;
-import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfo;
import org.apache.tomee.microprofile.jwt.ParseException;
+import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfo;
import java.net.URL;
import java.security.AccessController;
[27/38] tomee git commit: Fix Provider and Instance
Posted by jl...@apache.org.
Fix Provider and Instance
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/7b0c434d
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/7b0c434d
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/7b0c434d
Branch: refs/heads/master
Commit: 7b0c434dbe42c80d1bb276e7f24d27cee2ea6b74
Parents: cfc2ae1
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Fri Mar 2 16:20:21 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Fri Mar 2 16:20:21 2018 +0100
----------------------------------------------------------------------
.../org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java | 8 +++++++-
tck/mp-jwt-embedded/src/test/resources/dev.xml | 9 ++-------
2 files changed, 9 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/7b0c434d/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
index 0b6f3de..0d3488a 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
@@ -169,12 +169,18 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
// handle Provider<T>
if (rawTypeClass.isAssignableFrom(Provider.class)) {
final Type providerType = paramType.getActualTypeArguments()[0];
+ if (providerType instanceof ParameterizedType && isOptional((ParameterizedType) providerType)) {
+ return (T) Optional.ofNullable(getClaimValue(key));
+ }
return getClaimValue(key);
}
// handle Instance<T>
if (rawTypeClass.isAssignableFrom(Instance.class)) {
final Type instanceType = paramType.getActualTypeArguments()[0];
+ if (instanceType instanceof ParameterizedType && isOptional((ParameterizedType) instanceType)) {
+ return (T) Optional.ofNullable(getClaimValue(key));
+ }
return getClaimValue(key);
}
@@ -231,7 +237,7 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
return getClaimValue(key);
}
- throw new IllegalStateException("Unhandled ClaimValue type");
+ throw new IllegalStateException("Unhandled Claim type " + annotated.getBaseType());
}
public static String getClaimKey(final Claim claim) {
http://git-wip-us.apache.org/repos/asf/tomee/blob/7b0c434d/tck/mp-jwt-embedded/src/test/resources/dev.xml
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/test/resources/dev.xml b/tck/mp-jwt-embedded/src/test/resources/dev.xml
index b10e250..3814456 100644
--- a/tck/mp-jwt-embedded/src/test/resources/dev.xml
+++ b/tck/mp-jwt-embedded/src/test/resources/dev.xml
@@ -41,7 +41,6 @@
</run>
</groups>
<classes>
- <!-- OK
<class name="org.eclipse.microprofile.jwt.tck.parsing.TokenValidationTest" />
<class name="org.eclipse.microprofile.jwt.tck.util.TokenUtilsTest" />
<class name="org.eclipse.microprofile.jwt.tck.parsing.TestTokenClaimTypesTest" />
@@ -50,16 +49,12 @@
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.PrimitiveInjectionTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.ClaimValueInjectionTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.JsonValueInjectionTest" />
+ <class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.ProviderInjectionTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.RolesAllowedTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.InvalidTokenTest" />
- -->
- <class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.ProviderInjectionTest" />
- <!-- KO
- -->
</classes>
</test>
- <!--
<test name="extended-tests" verbose="10">
<groups>
<define name="extended-groups">
@@ -83,5 +78,5 @@
<class name="org.eclipse.microprofile.jwt.tck.container.jacc.SubjectTest" />
</classes>
</test>
- -->
+
</suite>
[29/38] tomee git commit: formating
Posted by jl...@apache.org.
formating
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/e75018b2
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/e75018b2
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/e75018b2
Branch: refs/heads/master
Commit: e75018b231942bec07c5a81fa513d476ab877877
Parents: 893525f
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Tue Mar 6 10:16:35 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Tue Mar 6 10:16:35 2018 +0100
----------------------------------------------------------------------
.../jwt/jaxrs/MPJWTSecurityAnnotationsInterceptor.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/e75018b2/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptor.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptor.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptor.java
index 60c2599..e6ccd5a 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptor.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptor.java
@@ -17,7 +17,8 @@ public class MPJWTSecurityAnnotationsInterceptor implements ContainerRequestFilt
private final Set<Method> denyAll;
private final Set<Method> permitAll;
- public MPJWTSecurityAnnotationsInterceptor(final javax.ws.rs.container.ResourceInfo resourceInfo, final ConcurrentMap<Method, Set<String>> rolesAllowed, final Set<Method> denyAll, final Set<Method> permitAll) {
+ public MPJWTSecurityAnnotationsInterceptor(final javax.ws.rs.container.ResourceInfo resourceInfo,
+ final ConcurrentMap<Method, Set<String>> rolesAllowed, final Set<Method> denyAll, final Set<Method> permitAll) {
this.resourceInfo = resourceInfo;
this.rolesAllowed = rolesAllowed;
this.denyAll = denyAll;
[38/38] tomee git commit: Merge remote-tracking branch
'github/master' into jlmonteiro-mp-jwt-playground
Posted by jl...@apache.org.
Merge remote-tracking branch 'github/master' into jlmonteiro-mp-jwt-playground
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/09ca434d
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/09ca434d
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/09ca434d
Branch: refs/heads/master
Commit: 09ca434d9d80de8a36e9973682e071e19934552f
Parents: d7b1ec6 3e487f0
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Tue Apr 17 00:16:25 2018 +0200
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Tue Apr 17 00:16:25 2018 +0200
----------------------------------------------------------------------
arquillian/arquillian-tomee-common/pom.xml | 2 +-
.../arquillian-tomee-webapp-remote/pom.xml | 2 +-
container/openejb-core/pom.xml | 4 ++--
.../config/PersistenceContextAnnFactory.java | 14 ++++++-------
.../apache/openejb/core/TempClassLoader.java | 6 +++---
.../openejb/core/cmp/cmp2/Cmp1Generator.java | 10 ++++-----
.../openejb/core/cmp/cmp2/Cmp2Generator.java | 12 +++++------
.../apache/openejb/core/cmp/cmp2/CmpField.java | 2 +-
.../apache/openejb/core/cmp/cmp2/CmrField.java | 2 +-
.../apache/openejb/core/cmp/cmp2/CmrStyle.java | 2 +-
.../core/cmp/cmp2/PostCreateGenerator.java | 8 +++----
.../apache/openejb/dyni/DynamicSubclass.java | 20 +++++++++---------
.../apache/openejb/util/AnnotationFinder.java | 16 +++++++-------
.../util/proxy/LocalBeanProxyFactory.java | 10 ++++-----
.../openejb/DependenceValidationTest.java | 4 ++--
.../org/apache/openejb/DependencyVisitor.java | 22 ++++++++++----------
.../openejb/config/ServiceClasspathTest.java | 16 +++++++-------
.../config/rules/KeysAnnotationVisitor.java | 8 +++----
.../config/rules/ValidationKeysAuditorTest.java | 4 ++--
.../apache/openejb/core/cmp/jpa/JpaTest.java | 14 ++++++-------
container/openejb-jpa-integration/pom.xml | 2 +-
.../openejb/jpa/integration/MakeTxLookup.java | 10 ++++-----
maven/maven-util/pom.xml | 5 +++++
pom.xml | 12 +++++------
server/openejb-bonecp/pom.xml | 5 +++++
server/openejb-common-cli/pom.xml | 6 +++++-
server/openejb-hessian/pom.xml | 5 +++++
server/openejb-hsql/pom.xml | 5 +++++
server/openejb-rest/pom.xml | 5 +++++
server/openejb-server/pom.xml | 2 +-
server/openejb-ssh/pom.xml | 5 +++++
server/openejb-webservices/pom.xml | 10 +++++++++
tck/bval-embedded/pom.xml | 5 +++++
tomee/apache-tomee/pom.xml | 2 +-
tomee/tomee-jaxrs/pom.xml | 5 +++++
tomee/tomee-loader/pom.xml | 5 +++++
tomee/tomee-webapp/pom.xml | 5 +++++
utils/openejb-mockito/pom.xml | 5 +++++
.../openejb/mockito/MockitoExtension.java | 2 +-
utils/openejb-provisionning/pom.xml | 5 +++++
40 files changed, 179 insertions(+), 105 deletions(-)
----------------------------------------------------------------------
[09/38] tomee git commit: Renaming
Posted by jl...@apache.org.
Renaming
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/ad9e2221
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/ad9e2221
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/ad9e2221
Branch: refs/heads/master
Commit: ad9e2221cdb1fe00e6f59d4b5ee46f1f24dabd4f
Parents: f58a39a
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Thu Feb 22 09:57:43 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Thu Feb 22 09:57:43 2018 +0100
----------------------------------------------------------------------
.../server/cxf/rs/MPJWTSecurityContextTest.java | 24 +++++++++-----------
1 file changed, 11 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/ad9e2221/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
----------------------------------------------------------------------
diff --git a/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
index c85e6fb..5c62851 100644
--- a/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
+++ b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
@@ -16,19 +16,19 @@
*/
package org.apache.openejb.server.cxf.rs;
+import org.apache.cxf.Bus;
+import org.apache.cxf.endpoint.Server;
import org.apache.cxf.jaxrs.model.ApplicationInfo;
import org.apache.openejb.jee.WebApp;
import org.apache.openejb.junit.ApplicationComposer;
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.observer.Observes;
-import org.apache.openejb.server.cxf.rs.event.ExtensionProviderRegistration;
import org.apache.openejb.server.cxf.rs.event.ServerCreated;
import org.apache.openejb.server.rest.InternalApplication;
import org.apache.openejb.spi.SecurityService;
import org.apache.openejb.testing.Classes;
import org.apache.openejb.testing.Configuration;
import org.apache.openejb.testing.EnableServices;
-import org.apache.openejb.testing.JaxrsProviders;
import org.apache.openejb.testing.Module;
import org.apache.openejb.testng.PropertiesBuilder;
import org.apache.openejb.util.NetworkUtil;
@@ -75,10 +75,10 @@ public class MPJWTSecurityContextTest {
}
@Module
- @Classes({ Res.class, RestApplication.class})
+ @Classes({Res.class, RestApplication.class})
public WebApp war() {
return new WebApp()
- .contextRoot("foo");
+ .contextRoot("foo");
}
@Test
@@ -122,35 +122,33 @@ public class MPJWTSecurityContextTest {
public void obs(@Observes final ServerCreated event) {
System.out.println("Observer.obs");
- final ApplicationInfo appInfo = (ApplicationInfo) event.getServer().getEndpoint().get("javax.ws.rs.core.Application");
+ final Server server = event.getServer();
+ final Bus bus = (Bus) server.getEndpoint().get("org.apache.cxf.Bus");
+ final ApplicationInfo appInfo = (ApplicationInfo) server.getEndpoint().get("javax.ws.rs.core.Application");
final Application application = InternalApplication.class.isInstance(appInfo.getProvider())
- ? InternalApplication.class.cast(appInfo.getProvider()).getOriginal()
- : appInfo.getProvider();
+ ? InternalApplication.class.cast(appInfo.getProvider()).getOriginal()
+ : appInfo.getProvider();
final LoginConfig annotation = application.getClass().getAnnotation(LoginConfig.class);
if (annotation != null && "MP-JWT".equals(annotation.authMethod())) {
// add the ContainerRequestFilter on the fly
- if (InternalApplication.class.isInstance(appInfo.getProvider())) {
- InternalApplication.class.cast(appInfo.getProvider()).getClasses().add(MySecuCtx.class);
- }
}
}
}
// this should also be packaged into the same module and delegate to the security service
@Provider
- public static class MySecuCtx implements ContainerRequestFilter {
+ public static class MPJWTSecurityContext implements ContainerRequestFilter {
private final SecurityService securityService;
- public MySecuCtx() {
+ public MPJWTSecurityContext() {
securityService = SystemInstance.get().getComponent(SecurityService.class);
Objects.requireNonNull(securityService, "A security context needs to be properly configured to enforce security in REST services");
}
@Override
public void filter(final ContainerRequestContext containerRequestContext) throws IOException {
-
containerRequestContext.setSecurityContext(new SecurityContext() {
@Override
public Principal getUserPrincipal() {
[10/38] tomee git commit: Integ test for MPJWT on TomEE
Posted by jl...@apache.org.
Integ test for MPJWT on TomEE
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/35e671d3
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/35e671d3
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/35e671d3
Branch: refs/heads/master
Commit: 35e671d395496a89316659e671d15609c534ef86
Parents: ad9e222
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Thu Feb 22 11:28:44 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Thu Feb 22 11:28:44 2018 +0100
----------------------------------------------------------------------
.../tests/jaxrs/mpjwt/HelloResource.java | 49 +++++++++++++
.../tests/jaxrs/mpjwt/MPJWTApplication.java | 28 +++++++
.../arquillian/tests/jaxrs/mpjwt/MPJWTTest.java | 77 ++++++++++++++++++++
3 files changed, 154 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/35e671d3/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/mpjwt/HelloResource.java
----------------------------------------------------------------------
diff --git a/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/mpjwt/HelloResource.java b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/mpjwt/HelloResource.java
new file mode 100644
index 0000000..bc030f1
--- /dev/null
+++ b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/mpjwt/HelloResource.java
@@ -0,0 +1,49 @@
+/*
+ * 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.openejb.arquillian.tests.jaxrs.mpjwt;
+
+import org.eclipse.microprofile.jwt.Claim;
+import org.eclipse.microprofile.jwt.ClaimValue;
+
+import javax.annotation.security.RolesAllowed;
+import javax.ejb.Lock;
+import javax.ejb.LockType;
+import javax.ejb.Stateless;
+import javax.inject.Inject;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.SecurityContext;
+
+@Path("/hello")
+@Stateless
+@Lock(LockType.READ)
+public class HelloResource {
+
+ @Inject
+ @Claim("jti")
+ private ClaimValue<String> jti;
+
+ @GET
+ @Produces(MediaType.TEXT_PLAIN)
+ @RolesAllowed("helloRole")
+ public String sayHello(@Context SecurityContext context) {
+ return "hello " + context.getUserPrincipal().getName();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/35e671d3/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/mpjwt/MPJWTApplication.java
----------------------------------------------------------------------
diff --git a/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/mpjwt/MPJWTApplication.java b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/mpjwt/MPJWTApplication.java
new file mode 100644
index 0000000..18bdee6
--- /dev/null
+++ b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/mpjwt/MPJWTApplication.java
@@ -0,0 +1,28 @@
+/*
+ * 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.openejb.arquillian.tests.jaxrs.mpjwt;
+
+import org.eclipse.microprofile.auth.LoginConfig;
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+
+@ApplicationPath("/api")
+@LoginConfig(authMethod = "MP-JWT")
+public class MPJWTApplication extends Application {
+ // discovered
+}
http://git-wip-us.apache.org/repos/asf/tomee/blob/35e671d3/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/mpjwt/MPJWTTest.java
----------------------------------------------------------------------
diff --git a/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/mpjwt/MPJWTTest.java b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/mpjwt/MPJWTTest.java
new file mode 100644
index 0000000..d29b2fc
--- /dev/null
+++ b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/mpjwt/MPJWTTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.openejb.arquillian.tests.jaxrs.mpjwt;
+
+import org.apache.openejb.arquillian.tests.jaxrs.staticresources.PreviousFilter;
+import org.apache.openejb.arquillian.tests.jaxrs.staticresources.SimpleServlet;
+import org.apache.openejb.arquillian.tests.jaxrs.staticresources.TheResource;
+import org.apache.ziplock.IO;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.net.URL;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(Arquillian.class)
+public class MPJWTTest {
+ @Deployment(testable = false)
+ public static Archive<?> war() {
+ return ShrinkWrap.create(WebArchive.class, "mpjwt.war")
+ .addClasses(TheResource.class, SimpleServlet.class, PreviousFilter.class, MPJWTApplication.class, HelloResource.class)
+ .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
+ .addAsWebResource(new StringAsset("static"), "index.html")
+ .addAsWebResource(new StringAsset("JSP <%= 5 %>"), "sample.jsp");
+ }
+
+ @ArquillianResource
+ private URL url;
+
+ @Test
+ public void jaxrs() throws IOException {
+ assertEquals("resource", IO.slurp(new URL(url.toExternalForm() + "api/the")));
+ }
+
+ @Test
+ public void staticResource() throws IOException {
+ assertEquals("static", IO.slurp(url));
+ }
+
+ @Test
+ public void servlet() throws IOException {
+ assertEquals("Servlet!", IO.slurp(new URL(url + "servlet")));
+ }
+
+ @Test
+ public void jsp() throws IOException {
+ assertEquals("JSP 5", IO.slurp(new URL(url + "sample.jsp")).trim());
+ }
+
+ @Test
+ public void filterOrder() throws IOException {
+ assertEquals("I'm the first", IO.slurp(new URL(url.toExternalForm() + "api/gotFilter")));
+ }
+}
[37/38] tomee git commit: Merge remote-tracking branch
'github/master' into jlmonteiro-mp-jwt-playground
Posted by jl...@apache.org.
Merge remote-tracking branch 'github/master' into jlmonteiro-mp-jwt-playground
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/d7b1ec64
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/d7b1ec64
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/d7b1ec64
Branch: refs/heads/master
Commit: d7b1ec640dde173d07b6f22cf8b4c5ddf2a26a68
Parents: 04675f5 3332c7e
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Wed Mar 7 11:45:37 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Wed Mar 7 11:45:37 2018 +0100
----------------------------------------------------------------------
...edExecutorServiceGetPrincipalInTaskTest.java | 11 +-
.../src/test/resources/managed/web.xml | 49 ++++++
.../arquillian/tests/jms/EnvEntryTest.java | 2 +
.../securityejb/SecurityEJBPropagationTest.java | 4 +-
.../src/test/resources/test/context.xml | 20 +++
.../org/apache/openejb/config/AutoConfig.java | 113 ++++++++++++-
.../openejb/core/mdb/MdbInstanceManager.java | 44 +++--
.../openejb/core/mdb/MdbPoolContainer.java | 8 +-
.../mdb/TxTimeoutPoolEndpointHandlerTest.java | 167 +++++++++++++++++++
.../superbiz/counter/CounterCallbacksTest.java | 2 +-
pom.xml | 9 +-
.../tomee/catalina/TomcatWebAppBuilder.java | 10 +-
.../tomee/embedded/ConnectorConfigTest.java | 4 +-
.../src/test/resources/test/context.xml | 2 +-
.../src/test/resources/test/login.config | 4 +-
15 files changed, 407 insertions(+), 42 deletions(-)
----------------------------------------------------------------------
[31/38] tomee git commit: Renamed to providers because the event
gives the existing list but it's up to the observer to add more
Posted by jl...@apache.org.
Renamed to providers because the event gives the existing list but it's up to the observer to add more
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/9a428e15
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/9a428e15
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/9a428e15
Branch: refs/heads/master
Commit: 9a428e151eea46cc0c0e5e0ffac01282b1ce1e98
Parents: ae7c21e
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Wed Mar 7 08:13:13 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Wed Mar 7 08:13:13 2018 +0100
----------------------------------------------------------------------
.../server/cxf/rs/event/ExtensionProviderRegistration.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/9a428e15/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/event/ExtensionProviderRegistration.java
----------------------------------------------------------------------
diff --git a/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/event/ExtensionProviderRegistration.java b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/event/ExtensionProviderRegistration.java
index cfae25c..932a6bf 100644
--- a/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/event/ExtensionProviderRegistration.java
+++ b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/event/ExtensionProviderRegistration.java
@@ -28,9 +28,9 @@ public class ExtensionProviderRegistration {
private final List<Object> providers;
private final AppContext appContext;
- public ExtensionProviderRegistration(final AppContext ctx, final List<Object> existings) {
+ public ExtensionProviderRegistration(final AppContext ctx, final List<Object> providers) {
this.appContext = ctx;
- this.providers = existings;
+ this.providers = providers;
}
public AppContext getAppContext() {
[35/38] tomee git commit: Not needed
Posted by jl...@apache.org.
Not needed
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/7446cbb0
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/7446cbb0
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/7446cbb0
Branch: refs/heads/master
Commit: 7446cbb0d062ffaa6009b1283822fe520f1aec3f
Parents: 3c089d3
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Wed Mar 7 11:31:36 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Wed Mar 7 11:31:36 2018 +0100
----------------------------------------------------------------------
.../openejb/core/security/JwtSecurityTest.java | 364 -------------------
1 file changed, 364 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/7446cbb0/container/openejb-core/src/test/java/org/apache/openejb/core/security/JwtSecurityTest.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/test/java/org/apache/openejb/core/security/JwtSecurityTest.java b/container/openejb-core/src/test/java/org/apache/openejb/core/security/JwtSecurityTest.java
deleted file mode 100644
index ddd92f3..0000000
--- a/container/openejb-core/src/test/java/org/apache/openejb/core/security/JwtSecurityTest.java
+++ /dev/null
@@ -1,364 +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.openejb.core.security;
-
-import org.apache.openejb.OpenEJB;
-import org.apache.openejb.assembler.classic.Assembler;
-import org.apache.openejb.assembler.classic.EjbJarInfo;
-import org.apache.openejb.assembler.classic.ProxyFactoryInfo;
-import org.apache.openejb.assembler.classic.SecurityServiceInfo;
-import org.apache.openejb.assembler.classic.StatelessSessionContainerInfo;
-import org.apache.openejb.assembler.classic.TransactionServiceInfo;
-import org.apache.openejb.config.ConfigurationFactory;
-import org.apache.openejb.core.LocalInitialContextFactory;
-import org.apache.openejb.core.security.jaas.GroupPrincipal;
-import org.apache.openejb.core.security.jaas.UserPrincipal;
-import org.apache.openejb.jee.EjbJar;
-import org.apache.openejb.jee.StatelessBean;
-import org.junit.AfterClass;
-import org.junit.Test;
-
-import javax.annotation.Resource;
-import javax.annotation.security.DeclareRoles;
-import javax.annotation.security.DenyAll;
-import javax.annotation.security.PermitAll;
-import javax.annotation.security.RolesAllowed;
-import javax.annotation.security.RunAs;
-import javax.ejb.SessionContext;
-import javax.ejb.Singleton;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.security.auth.Subject;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.login.AppConfigurationEntry;
-import javax.security.auth.login.Configuration;
-import javax.security.auth.login.LoginException;
-import javax.security.auth.spi.LoginModule;
-import java.security.Security;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.testng.AssertJUnit.assertFalse;
-
-public class JWTSecurityTest {
-
- @AfterClass
- public static void afterClass() throws Exception {
- OpenEJB.destroy();
- System.clearProperty(Context.INITIAL_CONTEXT_FACTORY);
- // unfortunate we can't reset the value, so setting to default (See Configuration)
- Security.setProperty("login.configuration.provider", "sun.security.provider.ConfigFile");
- }
-
- private Assembler configureAssembler(final String defaultUser) throws Exception {
- System.setProperty(Context.INITIAL_CONTEXT_FACTORY, LocalInitialContextFactory.class.getName());
- Security.setProperty("login.configuration.provider", JaasConfig.class.getName());
-
- final ConfigurationFactory config = new ConfigurationFactory();
- final Assembler assembler = new Assembler();
-
- assembler.createProxyFactory(config.configureService(ProxyFactoryInfo.class));
- assembler.createTransactionManager(config.configureService(TransactionServiceInfo.class));
-
- final SecurityServiceInfo serviceInfo = new SecurityServiceInfo();
- serviceInfo.service = "SecurityService";
- serviceInfo.className = SecurityServiceImpl.class.getName();
- serviceInfo.id = "New Security Service";
- serviceInfo.properties = new Properties();
- if (defaultUser != null) {
- // override the default user
- serviceInfo.properties.setProperty("DefaultUser", defaultUser);
-
- }
-
- assembler.createSecurityService(serviceInfo);
-
- // containers
- assembler.createContainer(config.configureService(StatelessSessionContainerInfo.class));
-
- final EjbJar ejbJar = new EjbJar("JwtTest");
-
- ejbJar.addEnterpriseBean(new StatelessBean(FooBean.class));
- ejbJar.addEnterpriseBean(new StatelessBean(BarBean.class));
-
- final EjbJarInfo ejbJarInfo = config.configureApplication(ejbJar);
-
- assembler.createApplication(ejbJarInfo);
-
- return assembler;
- }
-
- @Test
- public void test() throws Exception {
- final Assembler assembler = configureAssembler(null);
-
- final Properties props = new Properties();
- props.setProperty("openejb.authentication.realmName", "jwt-realm");
- props.setProperty(Context.SECURITY_PRINCIPAL, JWTUtil.createValidJwtAccessToken("committer", "community"));
- props.setProperty(Context.SECURITY_CREDENTIALS, "");
-
- final InitialContext ctx = new InitialContext(props);
-
- final Project foo = (Project) ctx.lookup("FooBeanLocal");
-
- foo.svnCheckout("");
- foo.svnCommit("");
-
- try {
- foo.deleteProject("");
- fail("Should not be allowed");
- } catch (final Exception e) {
- // good.
- }
-
- assertTrue("not in role committer", foo.isCallerInRole("committer"));
- assertTrue("not in role community", foo.isCallerInRole("community"));
- assertFalse("in role contributor", foo.isCallerInRole("contributor"));
- assertTrue("Caller is not jonathan", foo.isCaller("jonathan"));
-
- ctx.close();
- assembler.destroy();
- }
-
- // When no credentials are provided, the default user/role should be "guest"
- @Test
- public void testUnauthenticatedUser() throws Exception {
- final Assembler assembler = configureAssembler(null);
-
- // no credentials provided, the default user should be "guest"
- final Properties props = new Properties();
-
- final InitialContext ctx = new InitialContext(props);
-
- final Project foo = (Project) ctx.lookup("FooBeanLocal");
-
- foo.svnCheckout("");
- try {
- foo.svnCommit("");
- fail("Should not be allowed");
- } catch (final Exception e) {
- // good.
- }
-
- assertFalse("in role committer", foo.isCallerInRole("committer"));
- assertFalse("in role community", foo.isCallerInRole("community"));
- assertFalse("in role contributor", foo.isCallerInRole("contributor"));
- assertTrue("not in role guest", foo.isCallerInRole("guest"));
- assertTrue("Caller is not guest", foo.isCaller("guest"));
-
- ctx.close();
- assembler.destroy();
- }
-
- // Just to be sure we can override the default user (ie. guest)
- @Test
- public void testDefaultUser() throws Exception {
- final Assembler assembler = configureAssembler("public");
-
- // no credentials provided, the default user should be "guest"
- final Properties props = new Properties();
-
- final InitialContext ctx = new InitialContext(props);
-
- final Project foo = (Project) ctx.lookup("FooBeanLocal");
-
- foo.svnCheckout("");
- try {
- foo.svnCommit("");
- fail("Should not be allowed");
- } catch (final Exception e) {
- // good.
- }
-
- assertFalse("in role committer", foo.isCallerInRole("committer"));
- assertFalse("in role community", foo.isCallerInRole("community"));
- assertFalse("in role contributor", foo.isCallerInRole("contributor"));
- assertFalse("in role guest", foo.isCallerInRole("guest"));
- assertTrue("Caller is not public", foo.isCaller("public"));
-
- ctx.close();
- assembler.destroy();
- }
-
- @Singleton
- @DeclareRoles({"committer", "contributor", "community", "guest", "public"})
- public static class FooBean implements Project {
-
- @Resource
- private SessionContext context;
-
- @Override
- @RolesAllowed({"committer"})
- public String svnCommit(final String s) {
- return s;
- }
-
- @Override
- @RolesAllowed({"committer", "contributor"})
- public String submitPatch(final String s) {
- return s;
- }
-
- @Override
- @PermitAll
- public String svnCheckout(final String s) {
- return s;
- }
-
- @Override
- @DenyAll
- public String deleteProject(final String s) {
- return s;
- }
-
- @Override
- public boolean isCallerInRole(final String role) {
- return context.isCallerInRole(role);
- }
-
- @Override
- public boolean isCaller(final String user) {
- return context.getCallerPrincipal().getName().equals(user);
- }
- }
-
- @Singleton
- @RunAs("contributor")
- @DeclareRoles({"committer", "contributor", "community"})
- public static class BarBean implements Project {
-
- @Resource
- private SessionContext context;
-
- @Override
- @RolesAllowed({"committer"})
- public String svnCommit(final String s) {
- return s;
- }
-
- @Override
- @RolesAllowed({"committer", "contributor"})
- public String submitPatch(final String s) {
- return s;
- }
-
- @Override
- @PermitAll
- public String svnCheckout(final String s) {
- return s;
- }
-
- @Override
- @DenyAll
- public String deleteProject(final String s) {
- return s;
- }
-
- @Override
- @PermitAll
- public boolean isCallerInRole(final String role) {
- return context.isCallerInRole(role);
- }
-
- @Override
- @PermitAll
- public boolean isCaller(final String user) {
- return context.getCallerPrincipal().getName().equals(user);
- }
- }
-
- public interface Project {
-
- String svnCommit(String s);
-
- String submitPatch(String s);
-
- String svnCheckout(String s);
-
- String deleteProject(String s);
-
- boolean isCaller(String s);
-
- boolean isCallerInRole(String s);
- }
-
- public static class JaasConfig extends Configuration {
-
- @Override
- public AppConfigurationEntry[] getAppConfigurationEntry(final String name) {
- final Set<AppConfigurationEntry> entries = new HashSet<AppConfigurationEntry>();
-
- final Map<String, Object> options = new HashMap<String, Object>();
-
- entries.add(new AppConfigurationEntry(
- JWTLoginModule.class.getName(),
- AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
- options
- ));
- return entries.toArray(new AppConfigurationEntry[entries.size()]);
- }
- }
-
- public static class JWTLoginModule implements LoginModule {
-
- private Subject subject;
- private CallbackHandler callbackHandler;
- private Map<String, ?> sharedState;
- private Map<String, ?> options;
-
- @Override
- public void initialize(final Subject subject, final CallbackHandler callbackHandler, final Map<String, ?> sharedState, final Map<String, ?> options) {
- this.subject = subject;
- this.callbackHandler = callbackHandler;
- this.sharedState = sharedState;
- this.options = options;
- System.out.println("JWTLoginModule.initialize");
- }
-
- @Override
- public boolean login() throws LoginException {
- System.out.println("JWTLoginModule.login");
- subject.getPrincipals().add(new UserPrincipal("jonathan"));
- subject.getPrincipals().add(new GroupPrincipal("committer"));
- subject.getPrincipals().add(new GroupPrincipal("community"));
- return true;
- }
-
- @Override
- public boolean commit() throws LoginException {
- System.out.println("JWTLoginModule.commit");
- return true;
- }
-
- @Override
- public boolean abort() throws LoginException {
- System.out.println("JWTLoginModule.abort");
- return true;
- }
-
- @Override
- public boolean logout() throws LoginException {
- System.out.println("JWTLoginModule.logout");
- return true;
- }
- }
-}
[34/38] tomee git commit: Not needed
Posted by jl...@apache.org.
Not needed
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/3c089d35
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/3c089d35
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/3c089d35
Branch: refs/heads/master
Commit: 3c089d35e72987a93cfa3853f754e90cdbf8d267
Parents: 0340cef
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Wed Mar 7 11:30:44 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Wed Mar 7 11:30:44 2018 +0100
----------------------------------------------------------------------
.../tests/jaxrs/mpjwt/HelloResource.java | 49 -------------
.../tests/jaxrs/mpjwt/MPJWTApplication.java | 28 -------
.../arquillian/tests/jaxrs/mpjwt/MPJWTTest.java | 77 --------------------
3 files changed, 154 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/3c089d35/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/mpjwt/HelloResource.java
----------------------------------------------------------------------
diff --git a/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/mpjwt/HelloResource.java b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/mpjwt/HelloResource.java
deleted file mode 100644
index bc030f1..0000000
--- a/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/mpjwt/HelloResource.java
+++ /dev/null
@@ -1,49 +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.openejb.arquillian.tests.jaxrs.mpjwt;
-
-import org.eclipse.microprofile.jwt.Claim;
-import org.eclipse.microprofile.jwt.ClaimValue;
-
-import javax.annotation.security.RolesAllowed;
-import javax.ejb.Lock;
-import javax.ejb.LockType;
-import javax.ejb.Stateless;
-import javax.inject.Inject;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.SecurityContext;
-
-@Path("/hello")
-@Stateless
-@Lock(LockType.READ)
-public class HelloResource {
-
- @Inject
- @Claim("jti")
- private ClaimValue<String> jti;
-
- @GET
- @Produces(MediaType.TEXT_PLAIN)
- @RolesAllowed("helloRole")
- public String sayHello(@Context SecurityContext context) {
- return "hello " + context.getUserPrincipal().getName();
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/3c089d35/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/mpjwt/MPJWTApplication.java
----------------------------------------------------------------------
diff --git a/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/mpjwt/MPJWTApplication.java b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/mpjwt/MPJWTApplication.java
deleted file mode 100644
index 18bdee6..0000000
--- a/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/mpjwt/MPJWTApplication.java
+++ /dev/null
@@ -1,28 +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.openejb.arquillian.tests.jaxrs.mpjwt;
-
-import org.eclipse.microprofile.auth.LoginConfig;
-
-import javax.ws.rs.ApplicationPath;
-import javax.ws.rs.core.Application;
-
-@ApplicationPath("/api")
-@LoginConfig(authMethod = "MP-JWT")
-public class MPJWTApplication extends Application {
- // discovered
-}
http://git-wip-us.apache.org/repos/asf/tomee/blob/3c089d35/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/mpjwt/MPJWTTest.java
----------------------------------------------------------------------
diff --git a/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/mpjwt/MPJWTTest.java b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/mpjwt/MPJWTTest.java
deleted file mode 100644
index d29b2fc..0000000
--- a/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/mpjwt/MPJWTTest.java
+++ /dev/null
@@ -1,77 +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.openejb.arquillian.tests.jaxrs.mpjwt;
-
-import org.apache.openejb.arquillian.tests.jaxrs.staticresources.PreviousFilter;
-import org.apache.openejb.arquillian.tests.jaxrs.staticresources.SimpleServlet;
-import org.apache.openejb.arquillian.tests.jaxrs.staticresources.TheResource;
-import org.apache.ziplock.IO;
-import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.arquillian.junit.Arquillian;
-import org.jboss.arquillian.test.api.ArquillianResource;
-import org.jboss.shrinkwrap.api.Archive;
-import org.jboss.shrinkwrap.api.ShrinkWrap;
-import org.jboss.shrinkwrap.api.asset.EmptyAsset;
-import org.jboss.shrinkwrap.api.asset.StringAsset;
-import org.jboss.shrinkwrap.api.spec.WebArchive;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.IOException;
-import java.net.URL;
-
-import static org.junit.Assert.assertEquals;
-
-@RunWith(Arquillian.class)
-public class MPJWTTest {
- @Deployment(testable = false)
- public static Archive<?> war() {
- return ShrinkWrap.create(WebArchive.class, "mpjwt.war")
- .addClasses(TheResource.class, SimpleServlet.class, PreviousFilter.class, MPJWTApplication.class, HelloResource.class)
- .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
- .addAsWebResource(new StringAsset("static"), "index.html")
- .addAsWebResource(new StringAsset("JSP <%= 5 %>"), "sample.jsp");
- }
-
- @ArquillianResource
- private URL url;
-
- @Test
- public void jaxrs() throws IOException {
- assertEquals("resource", IO.slurp(new URL(url.toExternalForm() + "api/the")));
- }
-
- @Test
- public void staticResource() throws IOException {
- assertEquals("static", IO.slurp(url));
- }
-
- @Test
- public void servlet() throws IOException {
- assertEquals("Servlet!", IO.slurp(new URL(url + "servlet")));
- }
-
- @Test
- public void jsp() throws IOException {
- assertEquals("JSP 5", IO.slurp(new URL(url + "sample.jsp")).trim());
- }
-
- @Test
- public void filterOrder() throws IOException {
- assertEquals("I'm the first", IO.slurp(new URL(url.toExternalForm() + "api/gotFilter")));
- }
-}
[17/38] tomee git commit: some refactoring
Posted by jl...@apache.org.
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java
new file mode 100644
index 0000000..d69df02
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java
@@ -0,0 +1,75 @@
+/*
+ * 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.tomee.microprofile.jwt.cdi;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Optional;
+
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.spi.InjectionPoint;
+
+import org.eclipse.microprofile.jwt.Claim;
+import org.eclipse.microprofile.jwt.ClaimValue;
+import org.eclipse.microprofile.jwt.Claims;
+
+/**
+ * A producer for the ClaimValue<T> wrapper injection sites.
+ * @param <T> the raw claim type
+ */
+public class ClaimValueProducer<T> {
+
+ @Produces
+ @Claim("")
+ ClaimValue<T> produce(InjectionPoint ip) {
+ String name = getName(ip);
+ ClaimValue<Optional<T>> cv = MPJWTProducer.generalClaimValueProducer(name);
+ ClaimValue<T> returnValue = (ClaimValue<T>) cv;
+ Optional<T> value = cv.getValue();
+ // Pull out the ClaimValue<T> T type,
+ Type matchType = ip.getType();
+ Type actualType = Object.class;
+ boolean isOptional = false;
+ if (matchType instanceof ParameterizedType) {
+ actualType = ((ParameterizedType) matchType).getActualTypeArguments()[0];
+ isOptional = matchType.getTypeName().equals(Optional.class.getTypeName());
+ if (isOptional) {
+ actualType = ((ParameterizedType) matchType).getActualTypeArguments()[0];
+ }
+ }
+
+ if (!actualType.getTypeName().startsWith(Optional.class.getTypeName())) {
+ T nestedValue = value.orElse(null);
+ ClaimValueWrapper<T> wrapper = new ClaimValueWrapper<>(cv.getName());
+ wrapper.setValue(nestedValue);
+ returnValue = wrapper;
+ }
+ return returnValue;
+ }
+
+ String getName(InjectionPoint ip) {
+ String name = null;
+ for (Annotation ann : ip.getQualifiers()) {
+ if (ann instanceof Claim) {
+ Claim claim = (Claim) ann;
+ name = claim.standard() == Claims.UNKNOWN ? claim.value() : claim.standard().name();
+ }
+ }
+ return name;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java
new file mode 100644
index 0000000..6776191
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java
@@ -0,0 +1,54 @@
+/*
+ * 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.tomee.microprofile.jwt.cdi;
+
+import org.eclipse.microprofile.jwt.ClaimValue;
+
+/**
+ * An implementation of the ClaimValue interface
+ *
+ * @param <T> the claim value type
+ */
+public class ClaimValueWrapper<T> implements ClaimValue<T> {
+ private String name;
+
+ private T value;
+
+ public ClaimValueWrapper(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public T getValue() {
+ return value;
+ }
+
+ public void setValue(T value) {
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("ClaimValueWrapper[@%s], name=%s, value[%s]=%s", Integer.toHexString(hashCode()),
+ name, value.getClass(), value);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonValueProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonValueProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonValueProducer.java
new file mode 100644
index 0000000..2f991b2
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonValueProducer.java
@@ -0,0 +1,111 @@
+/*
+ * 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.tomee.microprofile.jwt.cdi;
+
+import org.eclipse.microprofile.jwt.Claim;
+import org.eclipse.microprofile.jwt.Claims;
+
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.json.JsonArray;
+import javax.json.JsonNumber;
+import javax.json.JsonObject;
+import javax.json.JsonString;
+import javax.json.JsonValue;
+import java.lang.annotation.Annotation;
+import java.util.Optional;
+import java.util.logging.Logger;
+
+/**
+ * A producer for JsonValue injection types
+ */
+public class JsonValueProducer {
+ private static Logger log = Logger.getLogger(JsonValueProducer.class.getName());
+
+ @Produces
+ @Claim("")
+ public JsonString getJsonString(InjectionPoint ip) {
+ return getValue(ip);
+ }
+
+ @Produces
+ @Claim("")
+ public Optional<JsonString> getOptionalJsonString(InjectionPoint ip) {
+ return getOptionalValue(ip);
+ }
+
+ @Produces
+ @Claim("")
+ public JsonNumber getJsonNumber(InjectionPoint ip) {
+ return getValue(ip);
+ }
+
+ @Produces
+ @Claim("")
+ public Optional<JsonNumber> getOptionalJsonNumber(InjectionPoint ip) {
+ return getOptionalValue(ip);
+ }
+
+ @Produces
+ @Claim("")
+ public JsonArray getJsonArray(InjectionPoint ip) {
+ return getValue(ip);
+ }
+
+ @Produces
+ @Claim("")
+ public Optional<JsonArray> getOptionalJsonArray(InjectionPoint ip) {
+ return getOptionalValue(ip);
+ }
+
+ @Produces
+ @Claim("")
+ public JsonObject getJsonObject(InjectionPoint ip) {
+ return getValue(ip);
+ }
+
+ @Produces
+ @Claim("")
+ public Optional<JsonObject> getOptionalJsonObject(InjectionPoint ip) {
+ return getOptionalValue(ip);
+ }
+
+ public <T extends JsonValue> T getValue(InjectionPoint ip) {
+ log.fine(String.format("JsonValueProducer(%s).produce", ip));
+ String name = getName(ip);
+ T jsonValue = (T) MPJWTProducer.generalJsonValueProducer(name);
+ return jsonValue;
+ }
+
+ public <T extends JsonValue> Optional<T> getOptionalValue(InjectionPoint ip) {
+ log.fine(String.format("JsonValueProducer(%s).produce", ip));
+ String name = getName(ip);
+ T jsonValue = (T) MPJWTProducer.generalJsonValueProducer(name);
+ return Optional.ofNullable(jsonValue);
+ }
+
+ String getName(InjectionPoint ip) {
+ String name = null;
+ for (Annotation ann : ip.getQualifiers()) {
+ if (ann instanceof Claim) {
+ Claim claim = (Claim) ann;
+ name = claim.standard() == Claims.UNKNOWN ? claim.value() : claim.standard().name();
+ }
+ }
+ return name;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
new file mode 100644
index 0000000..95e1aea
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTCDIExtension.java
@@ -0,0 +1,395 @@
+/*
+ * 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.tomee.microprofile.jwt.cdi;
+
+import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfoProvider;
+import org.apache.tomee.microprofile.jwt.MPJWTFilter;
+import org.apache.tomee.microprofile.jwt.MPJWTInitializer;
+import org.apache.tomee.microprofile.jwt.TCKTokenParser;
+import org.eclipse.microprofile.jwt.Claim;
+import org.eclipse.microprofile.jwt.Claims;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.SessionScoped;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.AfterDeploymentValidation;
+import javax.enterprise.inject.spi.BeanAttributes;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.BeforeBeanDiscovery;
+import javax.enterprise.inject.spi.DeploymentException;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.ProcessBeanAttributes;
+import javax.enterprise.inject.spi.ProcessInjectionPoint;
+import javax.enterprise.inject.spi.ProcessProducer;
+import javax.inject.Provider;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
+import java.util.logging.Logger;
+
+/**
+ * A CDI extension that provides a producer for the current authenticated JsonWebToken based on a thread
+ * local value that is managed by the {@link JWTAuthMechanism} request
+ * authentication handler.
+ * <p>
+ * This also installs the producer methods for the discovered:
+ * <ul>
+ * <li>@Claim ClaimValue<T> injection sites.</li>
+ * <li>@Claim raw type<T> injection sites.</li>
+ * <li>@Claim JsonValue injection sites.</li>
+ * </ul>
+ *
+ * @see JWTAuthMechanism
+ */
+public class MPJWTCDIExtension implements Extension {
+ private static Logger log = Logger.getLogger(MPJWTCDIExtension.class.getName());
+
+ /**
+ * Register the MPJWTProducer JsonWebToken producer bean
+ *
+ * @param bbd before discovery event
+ * @param beanManager cdi bean manager
+ */
+ public void observeBeforeBeanDiscovery(@Observes BeforeBeanDiscovery bbd, BeanManager beanManager) {
+ log.fine("MPJWTExtension(), added JWTPrincipalProducer");
+ bbd.addAnnotatedType(beanManager.createAnnotatedType(TCKTokenParser.class));
+ bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTFilter.class));
+ bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTInitializer.class));
+ bbd.addAnnotatedType(beanManager.createAnnotatedType(JWTAuthContextInfoProvider.class));
+ bbd.addAnnotatedType(beanManager.createAnnotatedType(MPJWTProducer.class));
+ bbd.addAnnotatedType(beanManager.createAnnotatedType(RawClaimTypeProducer.class));
+ bbd.addAnnotatedType(beanManager.createAnnotatedType(ClaimValueProducer.class));
+ bbd.addAnnotatedType(beanManager.createAnnotatedType(JsonValueProducer.class));
+ }
+
+ /**
+ * Replace the general producer method BeanAttributes with one bound to the collected injection site
+ * types to properly reflect all of the type locations the producer method applies to.
+ *
+ * @param pba the ProcessBeanAttributes
+ * @see ClaimProviderBeanAttributes
+ */
+ public void addTypeToClaimProducer(@Observes ProcessBeanAttributes pba) {
+ if (pba.getAnnotated().isAnnotationPresent(Claim.class)) {
+ Claim claim = pba.getAnnotated().getAnnotation(Claim.class);
+ if (claim.value().length() == 0 && claim.standard() == Claims.UNKNOWN) {
+ log.fine(String.format("addTypeToClaimProducer: %s\n", pba.getAnnotated()));
+ BeanAttributes delegate = pba.getBeanAttributes();
+ String name = delegate.getName();
+ if (delegate.getTypes().contains(Optional.class)) {
+ if (providerOptionalTypes.size() == 0) {
+ providerOptionalTypes.add(Optional.class);
+ }
+ pba.setBeanAttributes(new ClaimProviderBeanAttributes(delegate, providerOptionalTypes, providerQualifiers));
+ // This is
+ } else if (name != null && name.startsWith("RawClaimTypeProducer#")) {
+ if (rawTypes.size() == 0) {
+ rawTypes.add(Object.class);
+ }
+ pba.setBeanAttributes(new ClaimProviderBeanAttributes(delegate, rawTypes, rawTypeQualifiers));
+ log.fine(String.format("Setup RawClaimTypeProducer BeanAttributes"));
+ }
+ }
+ }
+ }
+
+ public void afterDeploymentValidation(@Observes AfterDeploymentValidation event, BeanManager beanManager) {
+ }
+
+ void doProcessProducers(@Observes ProcessProducer pp) {
+ }
+
+ /**
+ * Handle the non-{@linkplain Provider}, {@linkplain org.eclipse.microprofile.jwt.ClaimValue}, and
+ * {@linkplain javax.json.JsonValue} claim injection types.
+ *
+ * @param pip - the injection point event information
+ * @see RawClaimTypeProducer
+ */
+ void processClaimInjections(@Observes ProcessInjectionPoint pip) {
+ log.fine(String.format("pipRaw: %s", pip.getInjectionPoint()));
+ InjectionPoint ip = pip.getInjectionPoint();
+ if (ip.getAnnotated().isAnnotationPresent(Claim.class)) {
+ Claim claim = ip.getAnnotated().getAnnotation(Claim.class);
+ if (ip.getType() instanceof Class) {
+ Class rawClass = (Class) ip.getType();
+ // Primative types
+ if (Modifier.isFinal(rawClass.getModifiers())) {
+ rawTypes.add(ip.getType());
+ rawTypeQualifiers.add(claim);
+ log.fine(String.format("+++ Added Claim raw type: %s", ip.getType()));
+ Class declaringClass = ip.getMember().getDeclaringClass();
+ Annotation[] appScoped = declaringClass.getAnnotationsByType(ApplicationScoped.class);
+ Annotation[] sessionScoped = declaringClass.getAnnotationsByType(SessionScoped.class);
+ if ((appScoped != null && appScoped.length > 0) || (sessionScoped != null && sessionScoped.length > 0)) {
+ String err = String.format("A raw type cannot be injected into application/session scope: IP=%s", ip);
+ pip.addDefinitionError(new DeploymentException(err));
+ }
+ }
+ // This handles collections of primative types
+ } else if (isRawParameterizedType(ip.getType())) {
+ log.fine(String.format("+++ Added Claim ParameterizedType: %s", ip.getType()));
+ rawTypes.add(ip.getType());
+ rawTypeQualifiers.add(claim);
+ }
+ } else {
+ log.fine(String.format("Skipping pip: %s, type: %s/%s", ip, ip.getType(), ip.getType().getClass()));
+ }
+ }
+
+ /**
+ * Collect the types of all {@linkplain Provider} injection points annotated with {@linkplain Claim}.
+ *
+ * @param pip - the injection point event information
+ */
+ void processClaimProviderInjections(@Observes ProcessInjectionPoint<?, ? extends Provider> pip) {
+ log.fine(String.format("pip: %s", pip.getInjectionPoint()));
+ final InjectionPoint ip = pip.getInjectionPoint();
+ if (ip.getAnnotated().isAnnotationPresent(Claim.class)) {
+ Claim claim = ip.getAnnotated().getAnnotation(Claim.class);
+ if (claim.value().length() == 0 && claim.standard() == Claims.UNKNOWN) {
+ pip.addDefinitionError(new DeploymentException("@Claim at: " + ip + " has no name or valid standard enum setting"));
+ }
+ boolean usesEnum = claim.standard() != Claims.UNKNOWN;
+ final String claimName = usesEnum ? claim.standard().name() : claim.value();
+ log.fine(String.format("Checking Provider Claim(%s), ip: %s", claimName, ip));
+ ClaimIP claimIP = claims.get(claimName);
+ Type matchType = ip.getType();
+ // The T from the Provider<T> injection site
+ Type actualType = ((ParameterizedType) matchType).getActualTypeArguments()[0];
+ // Don't add Optional or JsonValue as this is handled specially
+ if (!optionalOrJsonValue(actualType)) {
+ rawTypes.add(actualType);
+ } else if (!actualType.getTypeName().startsWith("javax.json.Json")) {
+ // Validate that this is not an Optional<JsonValue>
+ Type innerType = ((ParameterizedType) actualType).getActualTypeArguments()[0];
+ if (!innerType.getTypeName().startsWith("javax.json.Json")) {
+ providerOptionalTypes.add(actualType);
+ providerQualifiers.add(claim);
+ }
+ }
+ rawTypeQualifiers.add(claim);
+ ClaimIPType key = new ClaimIPType(claimName, actualType);
+ if (claimIP == null) {
+ claimIP = new ClaimIP(actualType, actualType, false, claim);
+ claimIP.setProviderSite(true);
+ claims.put(key, claimIP);
+ }
+ claimIP.getInjectionPoints().add(ip);
+ log.fine(String.format("+++ Added Provider Claim(%s) ip: %s", claimName, ip));
+
+ }
+ }
+
+ /**
+ * Create producer methods for each ClaimValue injection site
+ *
+ * @param event - AfterBeanDiscovery
+ * @param beanManager - CDI bean manager
+ */
+ void observesAfterBeanDiscovery(@Observes final AfterBeanDiscovery event, final BeanManager beanManager) {
+ log.fine(String.format("observesAfterBeanDiscovery, %s", claims));
+ installClaimValueProducerMethodsViaSyntheticBeans(event, beanManager);
+
+ //installClaimValueProducesViaTemplateType(event, beanManager);
+ }
+
+ /**
+ * Create a synthetic bean with a custom Producer for the non-Provider injection sites.
+ *
+ * @param event - AfterBeanDiscovery
+ * @param beanManager - CDI bean manager
+ */
+ private void installClaimValueProducerMethodsViaSyntheticBeans(final AfterBeanDiscovery event, final BeanManager beanManager) {
+
+ }
+
+ private boolean optionalOrJsonValue(Type type) {
+ boolean isOptionOrJson = type.getTypeName().startsWith(Optional.class.getTypeName())
+ | type.getTypeName().startsWith("javax.json.Json");
+ return isOptionOrJson;
+ }
+
+ private boolean isRawParameterizedType(Type type) {
+ boolean isRawParameterizedType = false;
+ if (type instanceof ParameterizedType) {
+ ParameterizedType ptype = ParameterizedType.class.cast(type);
+ Type rawType = ptype.getRawType();
+ String rawTypeName = rawType.getTypeName();
+ isRawParameterizedType = !rawTypeName.startsWith("org.eclipse.microprofile.jwt");
+ }
+ return isRawParameterizedType;
+ }
+
+ /**
+ * A map of claim,type pairs to the injection site information
+ */
+ private HashMap<ClaimIPType, ClaimIP> claims = new HashMap<>();
+
+ private Set<Type> providerOptionalTypes = new HashSet<>();
+
+ private Set<Type> providerTypes = new HashSet<>();
+
+ private Set<Type> rawTypes = new HashSet<>();
+
+ private Set<Annotation> rawTypeQualifiers = new HashSet<>();
+
+ private Set<Annotation> providerQualifiers = new HashSet<>();
+
+ /**
+ * A key for a claim,injection site type pair
+ */
+ public static class ClaimIPType implements Comparable<ClaimIPType> {
+ public ClaimIPType(String claimName, Type ipType) {
+ this.claimName = claimName;
+ this.ipType = ipType;
+ }
+
+ /**
+ * Order the @Claim ClaimValue<T> on the @Claim.value and then T type name
+ *
+ * @param o - ClaimIP to compare to
+ * @return the ordering of this claim relative to o
+ */
+ @Override
+ public int compareTo(ClaimIPType o) {
+ int compareTo = claimName.compareTo(o.claimName);
+ if (compareTo == 0) {
+ compareTo = ipType.getTypeName().compareTo(o.ipType.getTypeName());
+ }
+ return compareTo;
+ }
+
+ private String claimName;
+
+ private Type ipType;
+ }
+
+ /**
+ * The representation of an @Claim annotated injection site
+ */
+ public static class ClaimIP {
+ /**
+ * Create a ClaimIP from the injection site information
+ *
+ * @param matchType - the outer type of the injection site
+ * @param valueType - the parameterized type of the injection site
+ * @param isOptional - is the injection site an Optional
+ * @param claim - the Claim qualifier
+ */
+ public ClaimIP(Type matchType, Type valueType, boolean isOptional, Claim claim) {
+ this.matchType = matchType;
+ this.valueType = valueType;
+ this.claim = claim;
+ }
+
+ public Type getMatchType() {
+ return matchType;
+ }
+
+ public String getClaimName() {
+ return claim.standard() == Claims.UNKNOWN ? claim.value() : claim.standard().name();
+ }
+
+ public Claim getClaim() {
+ return claim;
+ }
+
+ public Type getValueType() {
+ return valueType;
+ }
+
+ public boolean isOptional() {
+ return isOptional;
+ }
+
+ public boolean isProviderSite() {
+ return isProviderSite;
+ }
+
+ public void setProviderSite(boolean providerSite) {
+ this.isProviderSite = providerSite;
+ }
+
+ public boolean isNonStandard() {
+ return isNonStandard;
+ }
+
+ public void setNonStandard(boolean nonStandard) {
+ isNonStandard = nonStandard;
+ }
+
+ public boolean isJsonValue() {
+ return isJsonValue;
+ }
+
+ public void setJsonValue(boolean jsonValue) {
+ isJsonValue = jsonValue;
+ }
+
+ public Set<InjectionPoint> getInjectionPoints() {
+ return injectionPoints;
+ }
+
+ @Override
+ public String toString() {
+ return "ClaimIP{" +
+ "type=" + matchType +
+ ", claim=" + claim +
+ ", ips=" + injectionPoints +
+ '}';
+ }
+
+ /**
+ * The injection site value type
+ */
+ private Type matchType;
+
+ /**
+ * The actual type of of the ParameterizedType matchType
+ */
+ private Type valueType;
+
+ /**
+ * Is valueType actually wrapped in an Optional
+ */
+ private boolean isOptional;
+
+ private boolean isProviderSite;
+
+ private boolean isNonStandard;
+
+ private boolean isJsonValue;
+
+ /**
+ * The injection site @Claim annotation value
+ */
+ private Claim claim;
+
+ /**
+ * The location that share the @Claim/type combination
+ */
+ private HashSet<InjectionPoint> injectionPoints = new HashSet<>();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
new file mode 100644
index 0000000..f267437
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
@@ -0,0 +1,196 @@
+/*
+ * 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.tomee.microprofile.jwt.cdi;
+
+import org.eclipse.microprofile.jwt.ClaimValue;
+import org.eclipse.microprofile.jwt.JsonWebToken;
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.Destroyed;
+import javax.enterprise.context.Initialized;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Produces;
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+import javax.json.JsonValue;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.logging.Logger;
+
+/**
+ * A class that tracks the current validated MP-JWT and associated JsonWebToken via a thread
+ * local to provide a @RequestScoped JsonWebToken producer method.
+ * <p>
+ * It also provides utility methods for access the current JsonWebToken claim values.
+ */
+@ApplicationScoped
+public class MPJWTProducer {
+ private static Logger log = Logger.getLogger(MPJWTProducer.class.getName());
+ private static final String TMP = "tmp";
+ private static ThreadLocal<JsonWebToken> currentPrincipal = new ThreadLocal<>();
+
+ public static void setJWTPrincipal(JsonWebToken principal) {
+ currentPrincipal.set(principal);
+ }
+
+ public static JsonWebToken getJWTPrincpal() {
+ return currentPrincipal.get();
+ }
+
+ @PostConstruct
+ void init() {
+ log.fine("MPJWTProducer initialized");
+ }
+
+ void observeRequestInitialized(@Observes @Initialized(RequestScoped.class) Object event) {
+ log.finest(String.format("observeRequestInitialized, event=%s", event));
+ }
+
+ void observeRequestDestroyed(@Observes @Destroyed(RequestScoped.class) Object event) {
+ log.finest(String.format("observeRequestDestroyed, event=%s", event));
+ }
+
+ /**
+ * The @RequestScoped producer method for the current JsonWebToken
+ *
+ * @return
+ */
+ @Produces
+ @RequestScoped
+ JsonWebToken currentPrincipalOrNull() {
+ return currentPrincipal.get();
+ }
+
+ /**
+ * A utility method for accessing a claim from the current JsonWebToken as a ClaimValue<Optional<T>> object.
+ *
+ * @param name - name of the claim
+ * @param <T> expected actual type of the claim
+ * @return the claim value wrapper object
+ */
+ static <T> ClaimValue<Optional<T>> generalClaimValueProducer(String name) {
+ ClaimValueWrapper<Optional<T>> wrapper = new ClaimValueWrapper<>(name);
+ T value = getValue(name, false);
+ Optional<T> optValue = Optional.ofNullable(value);
+ wrapper.setValue(optValue);
+ return wrapper;
+ }
+
+ /**
+ * Return the indicated claim value as a JsonValue
+ *
+ * @param name - name of the claim
+ * @return a JsonValue wrapper
+ */
+ static JsonValue generalJsonValueProducer(String name) {
+ Object value = getValue(name, false);
+ JsonValue jsonValue = wrapValue(value);
+ return jsonValue;
+ }
+
+ public static <T> T getValue(String name, boolean isOptional) {
+ JsonWebToken jwt = getJWTPrincpal();
+ if (jwt == null) {
+ log.fine(String.format("getValue(%s), null JsonWebToken", name));
+ return null;
+ }
+
+ Optional<T> claimValue = jwt.claim(name);
+ if (!isOptional && !claimValue.isPresent()) {
+ log.fine(String.format("Failed to find Claim for: %s", name));
+ }
+ log.fine(String.format("getValue(%s), isOptional=%s, claimValue=%s", name, isOptional, claimValue));
+ return claimValue.orElse(null);
+ }
+
+ static JsonObject replaceMap(Map<String, Object> map) {
+ JsonObjectBuilder builder = Json.createObjectBuilder();
+ for (Map.Entry<String, Object> entry : map.entrySet()) {
+ Object entryValue = entry.getValue();
+ if (entryValue instanceof Map) {
+ JsonObject entryJsonObject = replaceMap((Map<String, Object>) entryValue);
+ builder.add(entry.getKey(), entryJsonObject);
+ } else if (entryValue instanceof List) {
+ JsonArray array = (JsonArray) wrapValue(entryValue);
+ builder.add(entry.getKey(), array);
+ } else if (entryValue instanceof Long || entryValue instanceof Integer) {
+ long lvalue = ((Number) entryValue).longValue();
+ builder.add(entry.getKey(), lvalue);
+ } else if (entryValue instanceof Double || entryValue instanceof Float) {
+ double dvalue = ((Number) entryValue).doubleValue();
+ builder.add(entry.getKey(), dvalue);
+ } else if (entryValue instanceof Boolean) {
+ boolean flag = ((Boolean) entryValue).booleanValue();
+ builder.add(entry.getKey(), flag);
+ } else if (entryValue instanceof String) {
+ builder.add(entry.getKey(), entryValue.toString());
+ }
+ }
+ return builder.build();
+ }
+
+ static JsonValue wrapValue(Object value) {
+ JsonValue jsonValue = null;
+ if (value instanceof JsonValue) {
+ // This may already be a JsonValue
+ jsonValue = (JsonValue) value;
+ } else if (value instanceof String) {
+ jsonValue = Json.createObjectBuilder()
+ .add(TMP, value.toString())
+ .build()
+ .getJsonString(TMP);
+ } else if (value instanceof Number) {
+ Number number = (Number) value;
+ if ((number instanceof Long) || (number instanceof Integer)) {
+ jsonValue = Json.createObjectBuilder()
+ .add(TMP, number.longValue())
+ .build()
+ .getJsonNumber(TMP);
+ } else {
+ jsonValue = Json.createObjectBuilder()
+ .add(TMP, number.doubleValue())
+ .build()
+ .getJsonNumber(TMP);
+ }
+ } else if (value instanceof Boolean) {
+ Boolean flag = (Boolean) value;
+ jsonValue = flag ? JsonValue.TRUE : JsonValue.FALSE;
+ } else if (value instanceof Collection) {
+ JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
+ Collection list = (Collection) value;
+ for (Object element : list) {
+ if (element instanceof String) {
+ arrayBuilder.add(element.toString());
+ } else {
+ JsonValue jvalue = wrapValue(element);
+ arrayBuilder.add(jvalue);
+ }
+ }
+ jsonValue = arrayBuilder.build();
+ } else if (value instanceof Map) {
+ jsonValue = replaceMap((Map) value);
+ }
+ return jsonValue;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/RawClaimTypeProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/RawClaimTypeProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/RawClaimTypeProducer.java
new file mode 100644
index 0000000..1ab817e
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/RawClaimTypeProducer.java
@@ -0,0 +1,69 @@
+/*
+ * 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.tomee.microprofile.jwt.cdi;
+
+import org.eclipse.microprofile.jwt.Claim;
+import org.eclipse.microprofile.jwt.ClaimValue;
+import org.eclipse.microprofile.jwt.Claims;
+
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.inject.Named;
+import java.lang.annotation.Annotation;
+import java.util.Optional;
+import java.util.logging.Logger;
+
+/**
+ *
+ */
+public class RawClaimTypeProducer {
+ private static Logger log = Logger.getLogger(RawClaimTypeProducer.class.getName());
+
+ @Produces
+ @Claim("")
+ @Named("RawClaimTypeProducer#getValue")
+ public Object getValue(InjectionPoint ip) {
+ log.fine(String.format("getValue(%s)", ip));
+ String name = getName(ip);
+ ClaimValue<Optional<Object>> cv = MPJWTProducer.generalClaimValueProducer(name);
+ Optional<Object> value = cv.getValue();
+ Object returnValue = value.orElse(null);
+ return returnValue;
+ }
+
+ @Produces
+ @Claim("")
+ @Named("RawClaimTypeProducer#getOptionalValue")
+ public Optional getOptionalValue(InjectionPoint ip) {
+ log.fine(String.format("getOptionalValue(%s)", ip));
+ String name = getName(ip);
+ ClaimValue<Optional<Object>> cv = MPJWTProducer.generalClaimValueProducer(name);
+ Optional<Object> value = cv.getValue();
+ return value;
+ }
+
+ String getName(InjectionPoint ip) {
+ String name = null;
+ for (Annotation ann : ip.getQualifiers()) {
+ if (ann instanceof Claim) {
+ Claim claim = (Claim) ann;
+ name = claim.standard() == Claims.UNKNOWN ? claim.value() : claim.standard().name();
+ }
+ }
+ return name;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfo.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfo.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfo.java
new file mode 100644
index 0000000..ef8c0b0
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfo.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.tomee.microprofile.jwt.config;
+
+import java.security.interfaces.RSAPublicKey;
+
+/**
+ * The public key and expected issuer needed to validate a token.
+ */
+public class JWTAuthContextInfo {
+ private RSAPublicKey signerKey;
+ private String issuedBy;
+ private int expGracePeriodSecs = 60;
+
+ public JWTAuthContextInfo() {
+ }
+
+ public JWTAuthContextInfo(RSAPublicKey signerKey, String issuedBy) {
+ this.signerKey = signerKey;
+ this.issuedBy = issuedBy;
+ }
+
+ public JWTAuthContextInfo(JWTAuthContextInfo orig) {
+ this.signerKey = orig.signerKey;
+ this.issuedBy = orig.issuedBy;
+ this.expGracePeriodSecs = orig.expGracePeriodSecs;
+ }
+
+ public RSAPublicKey getSignerKey() {
+ return signerKey;
+ }
+
+ public void setSignerKey(RSAPublicKey signerKey) {
+ this.signerKey = signerKey;
+ }
+
+ public String getIssuedBy() {
+ return issuedBy;
+ }
+
+ public void setIssuedBy(String issuedBy) {
+ this.issuedBy = issuedBy;
+ }
+
+ public int getExpGracePeriodSecs() {
+ return expGracePeriodSecs;
+ }
+
+ public void setExpGracePeriodSecs(int expGracePeriodSecs) {
+ this.expGracePeriodSecs = expGracePeriodSecs;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfoProvider.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfoProvider.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfoProvider.java
new file mode 100644
index 0000000..b810fcf
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/config/JWTAuthContextInfoProvider.java
@@ -0,0 +1,61 @@
+/*
+ * 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.tomee.microprofile.jwt.config;
+
+import org.apache.tomee.microprofile.jwt.KeyUtils;
+
+import javax.enterprise.context.Dependent;
+import javax.enterprise.inject.Produces;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Optional;
+
+@Dependent
+public class JWTAuthContextInfoProvider {
+
+ @Produces
+ Optional<JWTAuthContextInfo> getOptionalContextInfo() {
+ JWTAuthContextInfo contextInfo = new JWTAuthContextInfo();
+
+ // todo use MP Config to load the configuration
+ contextInfo.setIssuedBy("https://server.example.com");
+ RSAPublicKey pk = null;
+ try {
+ pk = (RSAPublicKey) KeyUtils.decodePublicKey("-----BEGIN RSA PUBLIC KEY-----\n" +
+ "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEq\n" +
+ "Fyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwR\n" +
+ "TYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5e\n" +
+ "UF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9\n" +
+ "AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYn\n" +
+ "sIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9x\n" +
+ "nQIDAQAB\n" +
+ "-----END RSA PUBLIC KEY-----\n");
+
+ } catch (final Exception e) {
+ e.printStackTrace();
+ // todo better handling
+ throw new RuntimeException(e);
+ }
+ contextInfo.setSignerKey(pk);
+
+ return Optional.of(contextInfo);
+ }
+
+ @Produces
+ JWTAuthContextInfo getContextInfo() {
+ return getOptionalContextInfo().get();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
new file mode 100644
index 0000000..120058d
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
@@ -0,0 +1,334 @@
+/*
+ * 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.tomee.microprofile.jwt.principal;
+
+import org.eclipse.microprofile.jwt.Claims;
+import org.jose4j.jwt.JwtClaims;
+import org.jose4j.jwt.MalformedClaimException;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonNumber;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+import javax.json.JsonValue;
+import javax.security.auth.Subject;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * A default implementation of JWTCallerPrincipal using jose4j
+ * Another implementation could use nimbus and another plain JSON-P
+ */
+public class DefaultJWTCallerPrincipal extends JWTCallerPrincipal {
+
+ private static Logger logger = Logger.getLogger(DefaultJWTCallerPrincipal.class.getName());
+ private String jwt;
+ private String type;
+ private JwtClaims claimsSet;
+
+ /**
+ * Create the DefaultJWTCallerPrincipal from the parsed JWT token and the extracted principal name
+ *
+ * @param jwt - the parsed JWT token representation
+ * @param name - the extracted unqiue name to use as the principal name; from "upn", "preferred_username" or "sub" claim
+ */
+ public DefaultJWTCallerPrincipal(String jwt, String type, JwtClaims claimsSet, String name) {
+ super(name);
+ this.jwt = jwt;
+ this.type = type;
+ this.claimsSet = claimsSet;
+ fixJoseTypes();
+ }
+
+ @Override
+ public Set<String> getAudience() {
+ Set<String> audSet = new HashSet<>();
+ try {
+ List<String> audList = claimsSet.getStringListClaimValue("aud");
+ if (audList != null) {
+ audSet.addAll(audList);
+ }
+ } catch (MalformedClaimException e) {
+ try {
+ String aud = claimsSet.getStringClaimValue("aud");
+ audSet.add(aud);
+ } catch (MalformedClaimException e1) {
+ }
+ }
+ return audSet;
+ }
+
+ @Override
+ public Set<String> getGroups() {
+ HashSet<String> groups = new HashSet<>();
+ try {
+ List<String> globalGroups = claimsSet.getStringListClaimValue("groups");
+ if (globalGroups != null) {
+ groups.addAll(globalGroups);
+ }
+ } catch (MalformedClaimException e) {
+ e.printStackTrace();
+ }
+ return groups;
+ }
+
+
+ @Override
+ public Set<String> getClaimNames() {
+ return new HashSet<>(claimsSet.getClaimNames());
+ }
+
+ @Override
+ public Object getClaim(String claimName) {
+ Claims claimType = Claims.UNKNOWN;
+ Object claim = null;
+ try {
+ claimType = Claims.valueOf(claimName);
+ } catch (IllegalArgumentException e) {
+ }
+ // Handle the jose4j NumericDate types and
+ switch (claimType) {
+ case exp:
+ case iat:
+ case auth_time:
+ case nbf:
+ case updated_at:
+ try {
+ claim = claimsSet.getClaimValue(claimType.name(), Long.class);
+ if (claim == null) {
+ claim = new Long(0);
+ }
+ } catch (MalformedClaimException e) {
+ }
+ break;
+ case groups:
+ claim = getGroups();
+ break;
+ case aud:
+ claim = getAudience();
+ break;
+ case UNKNOWN:
+ claim = claimsSet.getClaimValue(claimName);
+ break;
+ default:
+ claim = claimsSet.getClaimValue(claimType.name());
+ }
+ return claim;
+ }
+
+ @Override
+ public boolean implies(Subject subject) {
+ return false;
+ }
+
+ public String toString() {
+ return toString(false);
+ }
+
+ /**
+ * TODO: showAll is ignored and currently assumed true
+ *
+ * @param showAll - should all claims associated with the JWT be displayed or should only those defined in the
+ * JsonWebToken interface be displayed.
+ * @return JWTCallerPrincipal string view
+ */
+ @Override
+ public String toString(boolean showAll) {
+ String toString = "DefaultJWTCallerPrincipal{" +
+ "id='" + getTokenID() + '\'' +
+ ", name='" + getName() + '\'' +
+ ", expiration=" + getExpirationTime() +
+ ", notBefore=" + getClaim(Claims.nbf.name()) +
+ ", issuedAt=" + getIssuedAtTime() +
+ ", issuer='" + getIssuer() + '\'' +
+ ", audience=" + getAudience() +
+ ", subject='" + getSubject() + '\'' +
+ ", type='" + type + '\'' +
+ ", issuedFor='" + getClaim("azp") + '\'' +
+ ", authTime=" + getClaim("auth_time") +
+ ", givenName='" + getClaim("given_name") + '\'' +
+ ", familyName='" + getClaim("family_name") + '\'' +
+ ", middleName='" + getClaim("middle_name") + '\'' +
+ ", nickName='" + getClaim("nickname") + '\'' +
+ ", preferredUsername='" + getClaim("preferred_username") + '\'' +
+ ", email='" + getClaim("email") + '\'' +
+ ", emailVerified=" + getClaim(Claims.email_verified.name()) +
+ ", allowedOrigins=" + getClaim("allowedOrigins") +
+ ", updatedAt=" + getClaim("updated_at") +
+ ", acr='" + getClaim("acr") + '\'';
+ StringBuilder tmp = new StringBuilder(toString);
+ tmp.append(", groups=[");
+ for (String group : getGroups()) {
+ tmp.append(group);
+ tmp.append(',');
+ }
+ tmp.setLength(tmp.length() - 1);
+ tmp.append("]}");
+ return tmp.toString();
+ }
+
+ /**
+ * Convert the types jose4j uses for address, sub_jwk, and jwk
+ */
+ private void fixJoseTypes() {
+ if (claimsSet.hasClaim(Claims.address.name())) {
+ replaceMap(Claims.address.name());
+ }
+ if (claimsSet.hasClaim(Claims.jwk.name())) {
+ replaceMap(Claims.jwk.name());
+ }
+ if (claimsSet.hasClaim(Claims.sub_jwk.name())) {
+ replaceMap(Claims.sub_jwk.name());
+ }
+ // Handle custom claims
+ Set<String> customClaimNames = filterCustomClaimNames(claimsSet.getClaimNames());
+ for (String name : customClaimNames) {
+ Object claimValue = claimsSet.getClaimValue(name);
+ Class claimType = claimValue.getClass();
+ if (claimValue instanceof List) {
+ replaceList(name);
+ } else if (claimValue instanceof Map) {
+ replaceMap(name);
+ } else if (claimValue instanceof Number) {
+ replaceNumber(name);
+ }
+ }
+ }
+
+ /**
+ * Determine the custom claims in the set
+ *
+ * @param claimNames - the current set of claim names in this token
+ * @return the possibly empty set of names for non-Claims claims
+ */
+ private Set<String> filterCustomClaimNames(Collection<String> claimNames) {
+ HashSet<String> customNames = new HashSet<>(claimNames);
+ for (Claims claim : Claims.values()) {
+ customNames.remove(claim.name());
+ }
+ return customNames;
+ }
+
+ /**
+ * Replace the jose4j Map<String,Object> with a JsonObject
+ *
+ * @param name - claim name
+ */
+ private void replaceMap(String name) {
+ try {
+ Map<String, Object> map = claimsSet.getClaimValue(name, Map.class);
+ JsonObject jsonObject = replaceMap(map);
+ claimsSet.setClaim(name, jsonObject);
+ } catch (MalformedClaimException e) {
+ logger.log(Level.WARNING, "replaceMap failure for: " + name, e);
+ }
+ }
+
+ private JsonObject replaceMap(Map<String, Object> map) {
+ JsonObjectBuilder builder = Json.createObjectBuilder();
+ for (Map.Entry<String, Object> entry : map.entrySet()) {
+ Object entryValue = entry.getValue();
+ if (entryValue instanceof Map) {
+ JsonObject entryJsonObject = replaceMap((Map<String, Object>) entryValue);
+ builder.add(entry.getKey(), entryJsonObject);
+ } else if (entryValue instanceof List) {
+ JsonArray array = (JsonArray) wrapValue(entryValue);
+ builder.add(entry.getKey(), array);
+ } else if (entryValue instanceof Long || entryValue instanceof Integer) {
+ long lvalue = ((Number) entryValue).longValue();
+ builder.add(entry.getKey(), lvalue);
+ } else if (entryValue instanceof Double || entryValue instanceof Float) {
+ double dvalue = ((Number) entryValue).doubleValue();
+ builder.add(entry.getKey(), dvalue);
+ } else if (entryValue instanceof Boolean) {
+ boolean flag = ((Boolean) entryValue).booleanValue();
+ builder.add(entry.getKey(), flag);
+ } else if (entryValue instanceof String) {
+ builder.add(entry.getKey(), entryValue.toString());
+ }
+ }
+ return builder.build();
+ }
+
+ private JsonValue wrapValue(Object value) {
+ JsonValue jsonValue = null;
+ if (value instanceof Number) {
+ Number number = (Number) value;
+ if ((number instanceof Long) || (number instanceof Integer)) {
+ jsonValue = Json.createObjectBuilder()
+ .add("tmp", number.longValue())
+ .build()
+ .getJsonNumber("tmp");
+ } else {
+ jsonValue = Json.createObjectBuilder()
+ .add("tmp", number.doubleValue())
+ .build()
+ .getJsonNumber("tmp");
+ }
+ } else if (value instanceof Boolean) {
+ Boolean flag = (Boolean) value;
+ jsonValue = flag ? JsonValue.TRUE : JsonValue.FALSE;
+ } else if (value instanceof List) {
+ JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
+ List list = (List) value;
+ for (Object element : list) {
+ if (element instanceof String) {
+ arrayBuilder.add(element.toString());
+ } else {
+ JsonValue jvalue = wrapValue(element);
+ arrayBuilder.add(jvalue);
+ }
+ }
+ jsonValue = arrayBuilder.build();
+ }
+ return jsonValue;
+ }
+
+
+ /**
+ * Replace the jose4j List<?> with a JsonArray
+ *
+ * @param name - claim name
+ */
+ private void replaceList(String name) {
+ try {
+ List list = claimsSet.getClaimValue(name, List.class);
+ JsonArray array = (JsonArray) wrapValue(list);
+ claimsSet.setClaim(name, array);
+ } catch (MalformedClaimException e) {
+ logger.log(Level.WARNING, "replaceList failure for: " + name, e);
+ }
+ }
+
+ private void replaceNumber(String name) {
+ try {
+ Number number = claimsSet.getClaimValue(name, Number.class);
+ JsonNumber jsonNumber = (JsonNumber) wrapValue(number);
+ claimsSet.setClaim(name, jsonNumber);
+ } catch (MalformedClaimException e) {
+ logger.log(Level.WARNING, "replaceNumber failure for: " + name, e);
+ }
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipalFactory.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipalFactory.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipalFactory.java
new file mode 100644
index 0000000..a420dde
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipalFactory.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.tomee.microprofile.jwt.principal;
+
+import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfo;
+import org.apache.tomee.microprofile.jwt.ParseException;
+import org.eclipse.microprofile.jwt.Claims;
+import org.jose4j.jwa.AlgorithmConstraints;
+import org.jose4j.jws.AlgorithmIdentifiers;
+import org.jose4j.jwt.JwtClaims;
+import org.jose4j.jwt.MalformedClaimException;
+import org.jose4j.jwt.NumericDate;
+import org.jose4j.jwt.consumer.InvalidJwtException;
+import org.jose4j.jwt.consumer.JwtConsumer;
+import org.jose4j.jwt.consumer.JwtConsumerBuilder;
+import org.jose4j.jwt.consumer.JwtContext;
+
+/**
+ * A default implementation of the abstract JWTCallerPrincipalFactory that uses the Keycloak token parsing classes.
+ */
+public class DefaultJWTCallerPrincipalFactory extends JWTCallerPrincipalFactory {
+
+ /**
+ * Tries to load the JWTAuthContextInfo from CDI if the class level authContextInfo has not been set.
+ */
+ public DefaultJWTCallerPrincipalFactory() {
+ }
+
+ @Override
+ public JWTCallerPrincipal parse(final String token, final JWTAuthContextInfo authContextInfo) throws ParseException {
+ JWTCallerPrincipal principal = null;
+
+ try {
+ JwtConsumerBuilder builder = new JwtConsumerBuilder()
+ .setRequireExpirationTime()
+ .setRequireSubject()
+ .setSkipDefaultAudienceValidation()
+ .setExpectedIssuer(authContextInfo.getIssuedBy())
+ .setVerificationKey(authContextInfo.getSignerKey())
+ .setJwsAlgorithmConstraints(
+ new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.WHITELIST,
+ AlgorithmIdentifiers.RSA_USING_SHA256));
+ if (authContextInfo.getExpGracePeriodSecs() > 0) {
+ builder.setAllowedClockSkewInSeconds(authContextInfo.getExpGracePeriodSecs());
+ } else {
+ builder.setEvaluationTime(NumericDate.fromSeconds(0));
+ }
+
+ JwtConsumer jwtConsumer = builder.build();
+ JwtContext jwtContext = jwtConsumer.process(token);
+ String type = jwtContext.getJoseObjects().get(0).getHeader("typ");
+ // Validate the JWT and process it to the Claims
+ jwtConsumer.processContext(jwtContext);
+ JwtClaims claimsSet = jwtContext.getJwtClaims();
+
+ // We have to determine the unique name to use as the principal name. It comes from upn, preferred_username, sub in that order
+ String principalName = claimsSet.getClaimValue("upn", String.class);
+ if (principalName == null) {
+ principalName = claimsSet.getClaimValue("preferred_username", String.class);
+ if (principalName == null) {
+ principalName = claimsSet.getSubject();
+ }
+ }
+ claimsSet.setClaim(Claims.raw_token.name(), token);
+ principal = new DefaultJWTCallerPrincipal(token, type, claimsSet, principalName);
+ } catch (InvalidJwtException e) {
+ throw new ParseException("Failed to verify token", e);
+ } catch (MalformedClaimException e) {
+ throw new ParseException("Failed to verify token claims", e);
+ }
+
+ return principal;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipal.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipal.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipal.java
new file mode 100644
index 0000000..26d9406
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipal.java
@@ -0,0 +1,59 @@
+/*
+ * 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.tomee.microprofile.jwt.principal;
+
+
+import org.eclipse.microprofile.jwt.JsonWebToken;
+
+import java.util.Optional;
+
+/**
+ * An abstract CallerPrincipal implementation that provides access to the JWT claims that are required by
+ * the microprofile token.
+ */
+public abstract class JWTCallerPrincipal implements JsonWebToken {
+
+ private String name;
+
+ /**
+ * Create a JWTCallerPrincipal with the caller's name
+ *
+ * @param name - caller's name
+ */
+ public JWTCallerPrincipal(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Generate a human readable version of the caller principal and associated JWT.
+ *
+ * @param showAll - should all claims associated with the JWT be displayed or should only those defined in the
+ * JsonWebToken interface be displayed.
+ * @return human readable presentation of the caller principal and associated JWT.
+ */
+ public abstract String toString(boolean showAll);
+
+ public <T> Optional<T> claim(final String claimName) {
+ final T claim = (T) getClaim(claimName);
+ return Optional.ofNullable(claim);
+ }
+}
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipalFactory.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipalFactory.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipalFactory.java
new file mode 100644
index 0000000..3aec7f0
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/JWTCallerPrincipalFactory.java
@@ -0,0 +1,127 @@
+/*
+ * 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.tomee.microprofile.jwt.principal;
+
+import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfo;
+import org.apache.tomee.microprofile.jwt.ParseException;
+
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ServiceLoader;
+
+/**
+ * The factory class that provides the token string to JWTCallerPrincipal parsing for a given implementation.
+ */
+public abstract class JWTCallerPrincipalFactory {
+ private static JWTCallerPrincipalFactory instance;
+
+ /**
+ * Obtain the JWTCallerPrincipalFactory that has been set or by using the ServiceLoader pattern.
+ *
+ * @return the factory instance
+ * @see #setInstance(JWTCallerPrincipalFactory)
+ */
+ public static JWTCallerPrincipalFactory instance() {
+ if (instance == null) {
+ synchronized (JWTCallerPrincipalFactory.class) {
+ if (instance != null) {
+ return instance;
+ }
+
+ ClassLoader cl = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+ @Override
+ public ClassLoader run() {
+ return Thread.currentThread().getContextClassLoader();
+ }
+ });
+ if (cl == null) {
+ cl = JWTCallerPrincipalFactory.class.getClassLoader();
+ }
+
+ JWTCallerPrincipalFactory newInstance = loadSpi(cl);
+
+ if (newInstance == null && cl != JWTCallerPrincipalFactory.class.getClassLoader()) {
+ cl = JWTCallerPrincipalFactory.class.getClassLoader();
+ newInstance = loadSpi(cl);
+ }
+ if (newInstance == null) {
+ throw new IllegalStateException("No JWTCallerPrincipalFactory implementation found!");
+ }
+
+ instance = newInstance;
+ }
+ }
+
+ return instance;
+ }
+
+ /**
+ * Look for a JWTCallerPrincipalFactory service implementation using the ServiceLoader.
+ *
+ * @param cl - the ClassLoader to pass into the {@link ServiceLoader#load(Class, ClassLoader)} method.
+ * @return the JWTCallerPrincipalFactory if found, null otherwise
+ */
+ private static JWTCallerPrincipalFactory loadSpi(ClassLoader cl) {
+ if (cl == null) {
+ return null;
+ }
+
+ // start from the root CL and go back down to the TCCL
+ JWTCallerPrincipalFactory instance = loadSpi(cl.getParent());
+
+ if (instance == null) {
+ ServiceLoader<JWTCallerPrincipalFactory> sl = ServiceLoader.load(JWTCallerPrincipalFactory.class, cl);
+ URL u = cl.getResource("/META-INF/services/org.apache.tomee.microprofile.jwt.JWTCallerPrincipalFactory");
+ System.out.printf("JWTCallerPrincipalFactory, cl=%s, u=%s, sl=%s\n", cl, u, sl);
+ try {
+ for (JWTCallerPrincipalFactory spi : sl) {
+ if (instance != null) {
+ throw new IllegalStateException(
+ "Multiple JWTCallerPrincipalFactory implementations found: "
+ + spi.getClass().getName() + " and "
+ + instance.getClass().getName());
+ } else {
+ System.out.printf("sl=%s, loaded=%s\n", sl, spi);
+ instance = spi;
+ }
+ }
+ } catch (Throwable e) {
+ System.err.printf("Warning: %s\n", e.getMessage());
+ }
+ }
+ return instance;
+ }
+
+ /**
+ * Set the instance. It is used by OSGi environment where service loader pattern is not supported.
+ *
+ * @param resolver the instance to use.
+ */
+ public static void setInstance(JWTCallerPrincipalFactory resolver) {
+ instance = resolver;
+ }
+
+ /**
+ * Parse the given bearer token string into a JWTCallerPrincipal instance.
+ *
+ * @param token - the bearer token provided for authorization
+ * @return A JWTCallerPrincipal representation for the token.
+ * @throws ParseException on parse or verification failure.
+ */
+ public abstract JWTCallerPrincipal parse(String token, JWTAuthContextInfo authContextInfo) throws ParseException;
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/tck/mp-jwt-embedded/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
index 5e3bccc..d5eea47 100644
--- a/tck/mp-jwt-embedded/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
+++ b/tck/mp-jwt-embedded/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
@@ -1 +1 @@
-org.apache.tomee.microprofile.jwt.MPJWTCDIExtension
\ No newline at end of file
+org.apache.tomee.microprofile.jwt.cdi.MPJWTCDIExtension
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/resources/META-INF/services/org.apache.tomee.microprofile.jwt.JWTCallerPrincipalFactory
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/resources/META-INF/services/org.apache.tomee.microprofile.jwt.JWTCallerPrincipalFactory b/tck/mp-jwt-embedded/src/main/resources/META-INF/services/org.apache.tomee.microprofile.jwt.JWTCallerPrincipalFactory
deleted file mode 100644
index 67f39db..0000000
--- a/tck/mp-jwt-embedded/src/main/resources/META-INF/services/org.apache.tomee.microprofile.jwt.JWTCallerPrincipalFactory
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.tomee.microprofile.jwt.DefaultJWTCallerPrincipalFactory
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/c5964e07/tck/mp-jwt-embedded/src/main/resources/META-INF/services/org.apache.tomee.microprofile.jwt.principal.JWTCallerPrincipalFactory
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/resources/META-INF/services/org.apache.tomee.microprofile.jwt.principal.JWTCallerPrincipalFactory b/tck/mp-jwt-embedded/src/main/resources/META-INF/services/org.apache.tomee.microprofile.jwt.principal.JWTCallerPrincipalFactory
new file mode 100644
index 0000000..21c9831
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/resources/META-INF/services/org.apache.tomee.microprofile.jwt.principal.JWTCallerPrincipalFactory
@@ -0,0 +1 @@
+org.apache.tomee.microprofile.jwt.principal.DefaultJWTCallerPrincipalFactory
\ No newline at end of file
[07/38] tomee git commit: format
Posted by jl...@apache.org.
format
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/7d93131a
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/7d93131a
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/7d93131a
Branch: refs/heads/master
Commit: 7d93131a542f20ff6f4f0848f151a9ae71898602
Parents: 7acf314
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Wed Feb 21 17:09:29 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Wed Feb 21 17:09:29 2018 +0100
----------------------------------------------------------------------
.../org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java | 1 +
1 file changed, 1 insertion(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/7d93131a/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
----------------------------------------------------------------------
diff --git a/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
index 266aa66..28cc45d 100644
--- a/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
+++ b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
@@ -126,6 +126,7 @@ public class MPJWTSecurityContextTest {
final Application application = InternalApplication.class.isInstance(appInfo.getProvider())
? InternalApplication.class.cast(appInfo.getProvider()).getOriginal()
: appInfo.getProvider();
+
final LoginConfig annotation = application.getClass().getAnnotation(LoginConfig.class);
if (annotation != null && "MP-JWT".equals(annotation.authMethod())) {
// add the ContainerRequestFilter on the fly
[05/38] tomee git commit: chech the auth method
Posted by jl...@apache.org.
chech the auth method
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/a2468e4d
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/a2468e4d
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/a2468e4d
Branch: refs/heads/master
Commit: a2468e4dd19cb203124e7f0635772e56c3cbde7a
Parents: 9114b2a
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Wed Feb 21 16:31:53 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Wed Feb 21 16:31:53 2018 +0100
----------------------------------------------------------------------
.../org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/a2468e4d/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
----------------------------------------------------------------------
diff --git a/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
index ed13615..b7bceb5 100644
--- a/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
+++ b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
@@ -135,7 +135,7 @@ public class MPJWTSecurityContextTest {
final ApplicationInfo appInfo = (ApplicationInfo) registration.getServer().getEndpoint().get("javax.ws.rs.core.Application");
final Application application = appInfo.getProvider();
final LoginConfig annotation = application.getClass().getAnnotation(LoginConfig.class);
- if (annotation != null) {
+ if (annotation != null && "MP-JWT".equals(annotation.authMethod())) {
// add the ContainerRequestFilter on the fly
registration.getProviders().add(new MySecuCtx());
}
[14/38] tomee git commit: Token impl for TCK tests
Posted by jl...@apache.org.
Token impl for TCK tests
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/7639e0d2
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/7639e0d2
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/7639e0d2
Branch: refs/heads/master
Commit: 7639e0d2cbfdfe91305d7d1a24513da840e0e7ab
Parents: c5b38b3
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Thu Feb 22 22:48:14 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Thu Feb 22 22:48:14 2018 +0100
----------------------------------------------------------------------
.../apache/tomee/microprofile/jwt/TCKTokenParser.java | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/7639e0d2/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java
index b07ba24..ba57491 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java
@@ -20,14 +20,18 @@ import org.eclipse.microprofile.jwt.JsonWebToken;
import org.eclipse.microprofile.jwt.tck.util.ITokenParser;
import java.security.PublicKey;
+import java.security.interfaces.RSAPublicKey;
-// this is only used by the TCK
+/**
+ * MP-JWT TCK harness class to parse a token string
+ */
public class TCKTokenParser implements ITokenParser {
-
@Override
- public JsonWebToken parse(final String bearerToken, final String issuer, final PublicKey publicKey) throws Exception {
- return null; // todo - do some work
+ public JsonWebToken parse(String bearerToken, String issuer, PublicKey publicKey) throws Exception {
+ JWTAuthContextInfo authContextInfo = new JWTAuthContextInfo((RSAPublicKey) publicKey, issuer);
+ JWTCallerPrincipalFactory factory = DefaultJWTCallerPrincipalFactory.instance();
+ return factory.parse(bearerToken, authContextInfo);
}
}
[08/38] tomee git commit: comments
Posted by jl...@apache.org.
comments
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/f58a39aa
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/f58a39aa
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/f58a39aa
Branch: refs/heads/master
Commit: f58a39aaab0772839b149ccdc198b067924a648b
Parents: 7d93131
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Wed Feb 21 17:10:12 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Wed Feb 21 17:10:12 2018 +0100
----------------------------------------------------------------------
.../org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/f58a39aa/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
----------------------------------------------------------------------
diff --git a/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
index 28cc45d..c85e6fb 100644
--- a/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
+++ b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
@@ -103,7 +103,7 @@ public class MPJWTSecurityContextTest {
@LoginConfig(authMethod = "MP-JWT")
@ApplicationPath("/api")
public static class RestApplication extends Application {
-
+ // auto discovered
}
@Path("sc")
[04/38] tomee git commit: See if I can wire into the REST layer
Posted by jl...@apache.org.
See if I can wire into the REST layer
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/9114b2af
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/9114b2af
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/9114b2af
Branch: refs/heads/master
Commit: 9114b2afc89c06664fcb9a80b1757af729bc7e54
Parents: 7c7236b
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Wed Feb 21 16:29:21 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Wed Feb 21 16:29:21 2018 +0100
----------------------------------------------------------------------
.../server/cxf/rs/CxfRsHttpListener.java | 2 +-
.../rs/event/ExtensionProviderRegistration.java | 9 +-
.../server/cxf/rs/MPJWTSecurityContextTest.java | 183 +++++++++++++++++++
3 files changed, 192 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/9114b2af/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java
----------------------------------------------------------------------
diff --git a/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java
index e10172f..305a1c1 100644
--- a/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java
+++ b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java
@@ -1019,7 +1019,7 @@ public class CxfRsHttpListener implements RsHttpListener {
}
}
- SystemInstance.get().fireEvent(new ExtensionProviderRegistration(
+ SystemInstance.get().fireEvent(new ExtensionProviderRegistration(server,
AppFinder.findAppContextOrWeb(Thread.currentThread().getContextClassLoader(), AppFinder.AppContextTransformer.INSTANCE), providers));
if (!providers.isEmpty()) {
http://git-wip-us.apache.org/repos/asf/tomee/blob/9114b2af/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/event/ExtensionProviderRegistration.java
----------------------------------------------------------------------
diff --git a/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/event/ExtensionProviderRegistration.java b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/event/ExtensionProviderRegistration.java
index cfae25c..7af089f 100644
--- a/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/event/ExtensionProviderRegistration.java
+++ b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/event/ExtensionProviderRegistration.java
@@ -16,6 +16,7 @@
*/
package org.apache.openejb.server.cxf.rs.event;
+import org.apache.cxf.endpoint.Server;
import org.apache.openejb.AppContext;
import org.apache.openejb.observer.Event;
@@ -25,10 +26,12 @@ import java.util.List;
// this event can allow to add/remove/resort providers
@Event
public class ExtensionProviderRegistration {
+ private final Server server;
private final List<Object> providers;
private final AppContext appContext;
- public ExtensionProviderRegistration(final AppContext ctx, final List<Object> existings) {
+ public ExtensionProviderRegistration(final Server server, final AppContext ctx, final List<Object> existings) {
+ this.server = server;
this.appContext = ctx;
this.providers = existings;
}
@@ -41,6 +44,10 @@ public class ExtensionProviderRegistration {
return providers;
}
+ public Server getServer() {
+ return server;
+ }
+
@Override
public String toString() {
return "ExtensionProviderRegistration{}";
http://git-wip-us.apache.org/repos/asf/tomee/blob/9114b2af/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
----------------------------------------------------------------------
diff --git a/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
new file mode 100644
index 0000000..ed13615
--- /dev/null
+++ b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
@@ -0,0 +1,183 @@
+/*
+ * 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.openejb.server.cxf.rs;
+
+import org.apache.cxf.jaxrs.model.ApplicationInfo;
+import org.apache.openejb.jee.WebApp;
+import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.observer.Observes;
+import org.apache.openejb.server.cxf.rs.event.ExtensionProviderRegistration;
+import org.apache.openejb.server.cxf.rs.event.ServerCreated;
+import org.apache.openejb.spi.SecurityService;
+import org.apache.openejb.testing.Classes;
+import org.apache.openejb.testing.Configuration;
+import org.apache.openejb.testing.EnableServices;
+import org.apache.openejb.testing.JaxrsProviders;
+import org.apache.openejb.testing.Module;
+import org.apache.openejb.testng.PropertiesBuilder;
+import org.apache.openejb.util.NetworkUtil;
+import org.eclipse.microprofile.auth.LoginConfig;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.SecurityContext;
+import javax.ws.rs.ext.Provider;
+import java.io.IOException;
+import java.security.Principal;
+import java.util.Objects;
+import java.util.Properties;
+
+import static org.junit.Assert.assertEquals;
+
+@EnableServices("jax-rs")
+@RunWith(ApplicationComposer.class)
+public class MPJWTSecurityContextTest {
+
+ private static int port = -1;
+
+ @BeforeClass
+ public static void beforeClass() {
+ port = NetworkUtil.getNextAvailablePort();
+ }
+
+ @Configuration
+ public Properties props() {
+ return new PropertiesBuilder()
+ .p("httpejbd.port", Integer.toString(port))
+ .p("observer", "new://Service?class-name=" + Observer.class.getName()) // properly packaged and auto registered
+ .build();
+ }
+
+ @Module
+ @Classes({ Res.class, RestApplication.class})
+ public WebApp war() {
+ return new WebApp()
+ .contextRoot("foo");
+ }
+
+ @Test
+ public void check() throws IOException {
+ assertEquals("true", ClientBuilder.newClient()
+ .target("http://127.0.0.1:" + port)
+ .path("foo/sc")
+ .queryParam("role", "therole")
+ .request()
+ .accept(MediaType.TEXT_PLAIN_TYPE)
+ .get(String.class));
+
+ assertEquals("false", ClientBuilder.newClient()
+ .target("http://127.0.0.1:" + port)
+ .path("foo/sc")
+ .queryParam("role", "another")
+ .request()
+ .accept(MediaType.TEXT_PLAIN_TYPE)
+ .get(String.class));
+ }
+
+ @LoginConfig(authMethod = "MP-JWT")
+ @ApplicationPath("/api")
+ public class RestApplication extends Application {
+
+ }
+
+ @Path("sc")
+ public static class Res {
+ @Context
+ private SecurityContext sc;
+
+ @GET
+ public boolean f() {
+ return sc.isUserInRole("therole");
+ }
+ }
+
+ // this should go into a proper artifact for MP-JWT and have the property file so it gets discovered automatically
+ public static class Observer {
+
+ public void obs(@Observes final ServerCreated event) {
+ System.out.println("Observer.obs");
+ final ApplicationInfo appInfo = (ApplicationInfo) event.getServer().getEndpoint().get("javax.ws.rs.core.Application");
+ final Application application = appInfo.getProvider();
+ final LoginConfig annotation = application.getClass().getAnnotation(LoginConfig.class);
+ if (annotation != null) {
+ // add the ContainerRequestFilter on the fly
+ }
+ }
+
+ public void extension(@Observes final ExtensionProviderRegistration registration) {
+ System.out.println("Observer.extension");
+ // nothing useful here because we cannot access the application
+ final ApplicationInfo appInfo = (ApplicationInfo) registration.getServer().getEndpoint().get("javax.ws.rs.core.Application");
+ final Application application = appInfo.getProvider();
+ final LoginConfig annotation = application.getClass().getAnnotation(LoginConfig.class);
+ if (annotation != null) {
+ // add the ContainerRequestFilter on the fly
+ registration.getProviders().add(new MySecuCtx());
+ }
+ }
+ }
+
+ // this should also be packaged into the same module and delegate to the security service
+ @Provider
+ public static class MySecuCtx implements ContainerRequestFilter {
+
+ private final SecurityService securityService;
+
+ public MySecuCtx() {
+ securityService = SystemInstance.get().getComponent(SecurityService.class);
+ Objects.requireNonNull(securityService, "A security context needs to be properly configured to enforce security in REST services");
+ }
+
+ @Override
+ public void filter(final ContainerRequestContext containerRequestContext) throws IOException {
+
+ containerRequestContext.setSecurityContext(new SecurityContext() {
+ @Override
+ public Principal getUserPrincipal() {
+ return securityService.getCallerPrincipal();
+ }
+
+ @Override
+ public boolean isUserInRole(final String s) {
+ return securityService.isCallerInRole(s);
+ }
+
+ @Override
+ public boolean isSecure() {
+ return false;
+ }
+
+ @Override
+ public String getAuthenticationScheme() {
+ return "MP-JWT";
+ }
+ });
+ }
+ }
+
+}
[11/38] tomee git commit: Start adding a TCK module and implementing
some stuff
Posted by jl...@apache.org.
Start adding a TCK module and implementing some stuff
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/672b422e
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/672b422e
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/672b422e
Branch: refs/heads/master
Commit: 672b422ee8ad459d15fac5000d4a01013c01e2b3
Parents: 35e671d
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Thu Feb 22 16:58:13 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Thu Feb 22 16:58:13 2018 +0100
----------------------------------------------------------------------
.../server/cxf/rs/MPJWTSecurityContextTest.java | 7 +-
tck/mp-jwt-embedded/pom.xml | 157 +++++++++++++++++++
.../jwt/DefaultJWTCallerPrincipal.java | 51 ++++++
.../microprofile/jwt/JWTCallerPrincipal.java | 58 +++++++
.../tomee/microprofile/jwt/MPJWTFilter.java | 76 +++++++++
.../microprofile/jwt/MPJWTInitializer.java | 59 +++++++
.../tomee/microprofile/jwt/TCKTokenParser.java | 33 ++++
.../javax.servlet.ServletContainerInitializer | 1 +
tck/mp-jwt-embedded/src/test/resources/dev.xml | 80 ++++++++++
tck/pom.xml | 1 +
10 files changed, 520 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/672b422e/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
----------------------------------------------------------------------
diff --git a/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
index 5c62851..62565b4 100644
--- a/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
+++ b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/MPJWTSecurityContextTest.java
@@ -75,7 +75,7 @@ public class MPJWTSecurityContextTest {
}
@Module
- @Classes({Res.class, RestApplication.class})
+ @Classes(cdi = true, value = {Res.class, RestApplication.class})
public WebApp war() {
return new WebApp()
.contextRoot("foo");
@@ -85,7 +85,7 @@ public class MPJWTSecurityContextTest {
public void check() throws IOException {
assertEquals("true", ClientBuilder.newClient()
.target("http://127.0.0.1:" + port)
- .path("foo/sc")
+ .path("api/foo/sc")
.queryParam("role", "therole")
.request()
.accept(MediaType.TEXT_PLAIN_TYPE)
@@ -93,7 +93,7 @@ public class MPJWTSecurityContextTest {
assertEquals("false", ClientBuilder.newClient()
.target("http://127.0.0.1:" + port)
- .path("foo/sc")
+ .path("api/foo/sc")
.queryParam("role", "another")
.request()
.accept(MediaType.TEXT_PLAIN_TYPE)
@@ -132,6 +132,7 @@ public class MPJWTSecurityContextTest {
final LoginConfig annotation = application.getClass().getAnnotation(LoginConfig.class);
if (annotation != null && "MP-JWT".equals(annotation.authMethod())) {
// add the ContainerRequestFilter on the fly
+ // todo how to add this on the fly
}
}
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/672b422e/tck/mp-jwt-embedded/pom.xml
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/pom.xml b/tck/mp-jwt-embedded/pom.xml
new file mode 100644
index 0000000..361fd50
--- /dev/null
+++ b/tck/mp-jwt-embedded/pom.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <artifactId>tck</artifactId>
+ <groupId>org.apache.tomee</groupId>
+ <version>7.0.5-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>mp-jwt-embedded</artifactId>
+ <name>OpenEJB :: TCK :: MP-JWT Embedded</name>
+
+ <properties>
+ <tck.version>1.1-SNAPSHOT</tck.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>javaee-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>openejb-core</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-jdk14</artifactId>
+ <version>${slf4j.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>arquillian-tomee-embedded</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <!-- This is the MP-JWT TCK base extension and utility classes -->
+ <dependency>
+ <groupId>org.eclipse.microprofile.jwt</groupId>
+ <artifactId>microprofile-jwt-auth-tck</artifactId>
+ <version>${tck.version}</version>
+ </dependency>
+ <!-- This is the actual MP-JWT TCK test classes -->
+ <dependency>
+ <groupId>org.eclipse.microprofile.jwt</groupId>
+ <artifactId>microprofile-jwt-auth-tck</artifactId>
+ <version>${tck.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <!-- Arquillian extension SPI -->
+ <dependency>
+ <groupId>org.jboss.arquillian.container</groupId>
+ <artifactId>arquillian-container-spi</artifactId>
+ <version>${version.arquillian}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.arquillian.container</groupId>
+ <artifactId>arquillian-container-test-spi</artifactId>
+ <version>${version.arquillian}</version>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.10</version>
+ <executions>
+ <execution>
+ <id>copy-tck-test-suite-file</id>
+ <phase>generate-test-sources</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <stripVersion>true</stripVersion>
+ <artifactItems>
+ <artifactItem>
+ <groupId>org.eclipse.microprofile.jwt</groupId>
+ <artifactId>microprofile-jwt-auth-tck</artifactId>
+ <type>xml</type>
+ <classifier>suite</classifier>
+ <overWrite>false</overWrite>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.17</version>
+ <configuration>
+ <suiteXmlFiles>
+ <suiteXmlFile>${project.build.directory}/dependency/beanvalidation-tck-tests-suite.xml</suiteXmlFile>
+ </suiteXmlFiles>
+ <systemProperties>
+ <!--<property>-->
+ <!--<name>validation.provider</name>-->
+ <!--<value>${validation.provider}</value>-->
+ <!--</property>-->
+ </systemProperties>
+ <parallel>methods</parallel>
+ <threadCount>4</threadCount>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-report-plugin</artifactId>
+ <version>2.17</version>
+ <executions>
+ <execution>
+ <id>generate-test-report</id>
+ <phase>test</phase>
+ <goals>
+ <goal>report-only</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <outputDirectory>${project.build.directory}/surefire-reports</outputDirectory>
+ <outputName>test-report</outputName>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
http://git-wip-us.apache.org/repos/asf/tomee/blob/672b422e/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/DefaultJWTCallerPrincipal.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/DefaultJWTCallerPrincipal.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/DefaultJWTCallerPrincipal.java
new file mode 100644
index 0000000..d141a5f
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/DefaultJWTCallerPrincipal.java
@@ -0,0 +1,51 @@
+/*
+ * 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.tomee.microprofile.jwt;
+
+import java.util.Set;
+
+/**
+ * A default implementation of JWTCallerPrincipal that wraps Nimbus library used by default here
+ * We could create another implementation using plain JSON-P
+ *
+ */
+public class DefaultJWTCallerPrincipal extends JWTCallerPrincipal {
+
+ /**
+ * Create a JWTCallerPrincipal with the caller's name
+ *
+ * @param name - caller's name
+ */
+ public DefaultJWTCallerPrincipal(final String name) {
+ super(name);
+ }
+
+ @Override
+ public String toString(final boolean showAll) {
+ return null;
+ }
+
+ @Override
+ public Set<String> getClaimNames() {
+ return null;
+ }
+
+ @Override
+ public <T> T getClaim(final String claimName) {
+ return null;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/672b422e/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipal.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipal.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipal.java
new file mode 100644
index 0000000..3eca47b
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/JWTCallerPrincipal.java
@@ -0,0 +1,58 @@
+/*
+ * 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.tomee.microprofile.jwt;
+
+
+import java.util.Optional;
+import org.eclipse.microprofile.jwt.JsonWebToken;
+
+/**
+ * An abstract CallerPrincipal implementation that provides access to the JWT claims that are required by
+ * the microprofile token.
+ */
+public abstract class JWTCallerPrincipal implements JsonWebToken {
+ private String name;
+
+ /**
+ * Create a JWTCallerPrincipal with the caller's name
+ *
+ * @param name - caller's name
+ */
+ public JWTCallerPrincipal(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Generate a human readable version of the caller principal and associated JWT.
+ *
+ * @param showAll - should all claims associated with the JWT be displayed or should only those defined in the
+ * JsonWebToken interface be displayed.
+ * @return human readable presentation of the caller principal and associated JWT.
+ */
+ public abstract String toString(boolean showAll);
+
+ public <T> Optional<T> claim(String claimName) {
+ T claim = (T) getClaim(claimName);
+ return Optional.ofNullable(claim);
+ }
+}
http://git-wip-us.apache.org/repos/asf/tomee/blob/672b422e/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
new file mode 100644
index 0000000..9b57b51
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
@@ -0,0 +1,76 @@
+/*
+ * 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.tomee.microprofile.jwt;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.annotation.WebFilter;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import java.io.IOException;
+import java.security.Principal;
+
+// async is supported because we only need to do work on the way in
+@WebFilter(asyncSupported = true, urlPatterns = "/*")
+public class MPJWTFilter implements Filter {
+
+
+ @Override
+ public void init(final FilterConfig filterConfig) throws ServletException {
+ // get configuration
+
+ }
+
+ @Override
+ public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
+
+ final HttpServletRequest httpServletRequest = (HttpServletRequest)request;
+
+ // todo get JWT and do validation
+
+ // now wrap the httpServletRequest and override the principal so CXF can propagate into the SecurityContext
+ chain.doFilter(new HttpServletRequestWrapper(httpServletRequest) {
+
+ @Override
+ public Principal getUserPrincipal() {
+ return null; // todo, during parsing and validation, we need to convert into the JWT Principal as specified by the spec
+ }
+
+ @Override
+ public boolean isUserInRole(String role) {
+ return true; // replace with a check based on the claims content
+ }
+
+ @Override
+ public String getAuthType() {
+ return "MP-JWT";
+ }
+
+ }, response);
+
+ }
+
+ @Override
+ public void destroy() {
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/tomee/blob/672b422e/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
new file mode 100644
index 0000000..e91047d
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
@@ -0,0 +1,59 @@
+/*
+ * 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.tomee.microprofile.jwt;
+
+import org.eclipse.microprofile.auth.LoginConfig;
+
+import javax.servlet.FilterRegistration;
+import javax.servlet.ServletContainerInitializer;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.HandlesTypes;
+import javax.ws.rs.core.Application;
+import java.util.Set;
+
+/**
+ * Responsible for adding the filter into the chain and doing all other initialization
+ */
+@HandlesTypes(LoginConfig.class)
+public class MPJWTInitializer implements ServletContainerInitializer {
+
+ @Override
+ public void onStartup(final Set<Class<?>> classes, final ServletContext ctx) throws ServletException {
+
+ if (classes == null || classes.isEmpty()) {
+ return; // to REST application having @LoginConfig on it
+ }
+
+ for (Class<?> clazz : classes) {
+ final LoginConfig loginConfig = clazz.getAnnotation(LoginConfig.class);
+
+ if (loginConfig.authMethod() == null && !"MP-JWT".equals(loginConfig.authMethod())) {
+ continue;
+ }
+
+ if (!Application.class.isInstance(clazz)) {
+ continue; // do we really want Application?
+ }
+
+ final FilterRegistration.Dynamic mpJwtFilter = ctx.addFilter("mp-jwt-filter", MPJWTFilter.class);
+ mpJwtFilter.setAsyncSupported(true);
+ }
+
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/672b422e/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java
new file mode 100644
index 0000000..b07ba24
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/TCKTokenParser.java
@@ -0,0 +1,33 @@
+/*
+ * 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.tomee.microprofile.jwt;
+
+import org.eclipse.microprofile.jwt.JsonWebToken;
+import org.eclipse.microprofile.jwt.tck.util.ITokenParser;
+
+import java.security.PublicKey;
+
+// this is only used by the TCK
+public class TCKTokenParser implements ITokenParser {
+
+
+ @Override
+ public JsonWebToken parse(final String bearerToken, final String issuer, final PublicKey publicKey) throws Exception {
+ return null; // todo - do some work
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/tomee/blob/672b422e/tck/mp-jwt-embedded/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer b/tck/mp-jwt-embedded/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer
new file mode 100644
index 0000000..100e625
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer
@@ -0,0 +1 @@
+org.apache.tomee.microprofile.jwt.MPJWTInitializer
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/672b422e/tck/mp-jwt-embedded/src/test/resources/dev.xml
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/test/resources/dev.xml b/tck/mp-jwt-embedded/src/test/resources/dev.xml
new file mode 100644
index 0000000..c2b24b8
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/test/resources/dev.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
+<suite name="microprofile-jwt-auth-FullTCK" verbose="1" preserve-order="true" configfailurepolicy="continue" >
+
+ <!-- The required base JAX-RS and CDI based tests that all MP-JWT implementations
+ must pass.
+ -->
+ <test name="base-tests" verbose="10">
+ <groups>
+ <define name="base-groups">
+ <include name="arquillian" description="Arquillian internal"/>
+ <include name="utils" description="Utility tests"/>
+ <include name="jwt" description="Base JsonWebToken tests"/>
+ <include name="jaxrs" description="JAX-RS invocation tests"/>
+ <include name="cdi" description="Base CDI injection of ClaimValues"/>
+ <include name="cdi-json" description="CDI injection of JSON-P values"/>
+ <include name="cdi-provider" description="CDI injection of javax.inject.Provider values"/>
+ </define>
+ <define name="excludes">
+ <include name="debug" description="Internal debugging tests" />
+ </define>
+ <run>
+ <include name="base-groups" />
+ <exclude name="excludes" />
+ </run>
+ </groups>
+ <classes>
+ <class name="org.eclipse.microprofile.jwt.tck.parsing.TokenValidationTest" />
+ <class name="org.eclipse.microprofile.jwt.tck.util.TokenUtilsTest" />
+ <class name="org.eclipse.microprofile.jwt.tck.parsing.TestTokenClaimTypesTest" />
+ <class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.UnsecuredPingTest" />
+ <class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.RequiredClaimsTest" />
+ <class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.ClaimValueInjectionTest" />
+ <class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.JsonValueInjectionTest" />
+ <class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.ProviderInjectionTest" />
+ <class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.RolesAllowedTest" />
+ <class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.InvalidTokenTest" />
+ </classes>
+ </test>
+ <test name="extended-tests" verbose="10">
+ <groups>
+ <define name="extended-groups">
+ <include name="arquillian" description="Arquillian internal"/>
+ <include name="ejb-optional" description="EJB container integration tests"/>
+ <include name="jacc-optional" description="JACC API integration tests"/>
+ <include name="servlet-optional" description="Servlet container integration tests"/>
+ <include name="ee-security-optional" description="Java EE security feature tests"/>
+ </define>
+ <define name="excludes">
+ <include name="debug" description="Internal debugging tests" />
+ </define>
+ <run>
+ <include name="extended-groups" />
+ <exclude name="excludes" />
+ </run>
+ </groups>
+ <classes>
+ <class name="org.eclipse.microprofile.jwt.tck.container.ejb.EjbTest" />
+ <class name="org.eclipse.microprofile.jwt.tck.container.jacc.SubjectTest" />
+ <class name="org.eclipse.microprofile.jwt.tck.container.servlet.ServletTest" />
+ </classes>
+
+ </test>
+</suite>
http://git-wip-us.apache.org/repos/asf/tomee/blob/672b422e/tck/pom.xml
----------------------------------------------------------------------
diff --git a/tck/pom.xml b/tck/pom.xml
index 774c80b..d2c877c 100644
--- a/tck/pom.xml
+++ b/tck/pom.xml
@@ -36,6 +36,7 @@
<module>cdi-embedded</module>
<module>cdi-tomee</module>
<module>bval-tomee</module>
+ <module>mp-jwt-embedded</module>
<!-- TODO: either really use this module or delete it -->
<module>bval-embedded</module>
[28/38] tomee git commit: cleanup and implement EJB integration
Posted by jl...@apache.org.
cleanup and implement EJB integration
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/893525f8
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/893525f8
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/893525f8
Branch: refs/heads/master
Commit: 893525f860c485b5c5d0a79cb1621de3f56e8013
Parents: 7b0c434
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Tue Mar 6 10:13:04 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Tue Mar 6 10:13:04 2018 +0100
----------------------------------------------------------------------
.../core/security/AbstractSecurityService.java | 9 +-
tck/mp-jwt-embedded/pom.xml | 14 +-
.../tomee/microprofile/jwt/MPJWTContext.java | 129 -----------
.../tomee/microprofile/jwt/MPJWTFilter.java | 230 +++++++++++++++----
.../microprofile/jwt/MPJWTInitializer.java | 15 +-
.../tomee/microprofile/jwt/cdi/ClaimBean.java | 46 ++--
.../microprofile/jwt/cdi/ClaimValueWrapper.java | 10 +-
.../microprofile/jwt/cdi/JsonbProducer.java | 1 +
.../microprofile/jwt/cdi/MPJWTProducer.java | 28 ++-
.../jwt/jaxrs/MPJWPProviderRegistration.java | 46 ++++
.../MPJWTSecurityAnnotationsInterceptor.java | 54 +++++
...TSecurityAnnotationsInterceptorsFeature.java | 144 ++++++++++++
.../META-INF/org.apache.openejb.extension | 1 +
tck/mp-jwt-embedded/src/test/resources/dev.xml | 13 +-
.../tomee/catalina/TomcatSecurityService.java | 20 ++
15 files changed, 532 insertions(+), 228 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/893525f8/container/openejb-core/src/main/java/org/apache/openejb/core/security/AbstractSecurityService.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/core/security/AbstractSecurityService.java b/container/openejb-core/src/main/java/org/apache/openejb/core/security/AbstractSecurityService.java
index 57e2c9c..514847b 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/core/security/AbstractSecurityService.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/core/security/AbstractSecurityService.java
@@ -53,6 +53,7 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.UUID;
+import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
/**
@@ -153,13 +154,13 @@ public abstract class AbstractSecurityService implements DestroyableResource, Se
final ProvidedSecurityContext providedSecurityContext = newContext.get(ProvidedSecurityContext.class);
SecurityContext securityContext = oldContext != null ? oldContext.get(SecurityContext.class) :
- (providedSecurityContext != null ? providedSecurityContext.context : null);
+ (providedSecurityContext != null ? providedSecurityContext.context : null);
if (providedSecurityContext == null && (securityContext == null || securityContext == defaultContext)) {
final Identity identity = clientIdentity.get();
if (identity != null) {
securityContext = new SecurityContext(identity.subject);
} else {
- securityContext = defaultContext;
+ securityContext = getDefaultContext();
}
}
@@ -398,6 +399,10 @@ public abstract class AbstractSecurityService implements DestroyableResource, Se
}
}
+ protected SecurityContext getDefaultContext() {
+ return defaultContext;
+ }
+
public static final class ProvidedSecurityContext {
public final SecurityContext context;
http://git-wip-us.apache.org/repos/asf/tomee/blob/893525f8/tck/mp-jwt-embedded/pom.xml
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/pom.xml b/tck/mp-jwt-embedded/pom.xml
index 5055ac4..2af8f28 100644
--- a/tck/mp-jwt-embedded/pom.xml
+++ b/tck/mp-jwt-embedded/pom.xml
@@ -40,7 +40,13 @@
<groupId>${project.groupId}</groupId>
<artifactId>openejb-core</artifactId>
<version>${project.version}</version>
- <scope>test</scope>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>openejb-cxf-rs</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
@@ -112,6 +118,12 @@
<artifactId>johnzon-jsonb</artifactId>
<version>1.1.2</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.tomcat</groupId>
+ <artifactId>tomcat-catalina</artifactId>
+ <version>${tomcat.version}</version>
+ <scope>provided</scope>
+ </dependency>
</dependencies>
<build>
http://git-wip-us.apache.org/repos/asf/tomee/blob/893525f8/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTContext.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTContext.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTContext.java
deleted file mode 100644
index 50b7d1e..0000000
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTContext.java
+++ /dev/null
@@ -1,129 +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.tomee.microprofile.jwt;
-
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.function.Predicate;
-
-/**
- * Responsible for holding the runtime model
- */
-public class MPJWTContext {
-
- private static final ConcurrentMap<MPJWTConfigKey, MPJWTConfigValue> configuration = new ConcurrentHashMap<>();
-
- public static MPJWTConfigValue addMapping(final MPJWTConfigKey key, final MPJWTConfigValue value) {
- Objects.requireNonNull(key, "MP JWT Key is required");
- Objects.requireNonNull(value, "MP JWT Value is required");
-
- final MPJWTConfigValue oldValue = configuration.putIfAbsent(key, value);
- if (oldValue != null) {
- throw new IllegalStateException("A mapping has already been defined for the key " + key);
- }
-
- return value;
- }
-
- public static Optional<MPJWTConfigValue> get(final MPJWTConfigKey key) {
- Objects.requireNonNull(key, "MP JWT Key is required to retrieve the configuration");
- return Optional.ofNullable(configuration.get(key));
- }
-
- public static Optional<Map.Entry<MPJWTConfigKey, MPJWTConfigValue>> findFirst(final String path) {
- return configuration.entrySet()
- .stream()
- .filter(new Predicate<ConcurrentMap.Entry<MPJWTConfigKey, MPJWTConfigValue>>() {
- @Override
- public boolean test(final ConcurrentMap.Entry<MPJWTConfigKey, MPJWTConfigValue> e) {
- return path.startsWith(e.getKey().toURI());
- }
- })
- .findFirst();
- }
-
-
- public static class MPJWTConfigValue {
- private final String authMethod;
- private final String realm;
-
- public MPJWTConfigValue(final String authMethod, final String realm) {
- this.authMethod = authMethod;
- this.realm = realm;
- }
-
- public String getAuthMethod() {
- return authMethod;
- }
-
- public String getRealm() {
- return realm;
- }
- }
-
- public static class MPJWTConfigKey {
- private final String contextPath;
- private final String applicationPath;
-
- public MPJWTConfigKey(final String contextPath, final String applicationPath) {
- this.contextPath = contextPath;
- this.applicationPath = applicationPath;
- }
-
- public String getApplicationPath() {
- return applicationPath;
- }
-
- public String getContextPath() {
- return contextPath;
- }
-
- public String toURI() {
- return ("/" + contextPath + "/" + applicationPath).replaceAll("//", "/");
- }
-
- @Override
- public boolean equals(final Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- final MPJWTConfigKey that = (MPJWTConfigKey) o;
-
- if (contextPath != null ? !contextPath.equals(that.contextPath) : that.contextPath != null) return false;
- return !(applicationPath != null ? !applicationPath.equals(that.applicationPath) : that.applicationPath != null);
-
- }
-
- @Override
- public int hashCode() {
- int result = contextPath != null ? contextPath.hashCode() : 0;
- result = 31 * result + (applicationPath != null ? applicationPath.hashCode() : 0);
- return result;
- }
-
- @Override
- public String toString() {
- return "MPJWTConfigKey{" +
- "applicationPath='" + applicationPath + '\'' +
- ", contextPath='" + contextPath + '\'' +
- '}';
- }
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/893525f8/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
index 36e53cf..87ab714 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
@@ -16,13 +16,12 @@
*/
package org.apache.tomee.microprofile.jwt;
-import org.apache.tomee.microprofile.jwt.cdi.MPJWTProducer;
import org.apache.tomee.microprofile.jwt.config.JWTAuthContextInfo;
-import org.apache.tomee.microprofile.jwt.principal.DefaultJWTCallerPrincipalFactory;
import org.apache.tomee.microprofile.jwt.principal.JWTCallerPrincipalFactory;
import org.eclipse.microprofile.jwt.JsonWebToken;
import javax.inject.Inject;
+import javax.security.auth.Subject;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
@@ -33,11 +32,18 @@ import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.security.Principal;
+import java.util.Collections;
+import java.util.LinkedHashSet;
import java.util.Locale;
-import java.util.Map;
-import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.function.Function;
+import java.util.stream.Collectors;
// async is supported because we only need to do work on the way in
@WebFilter(asyncSupported = true, urlPatterns = "/*")
@@ -56,74 +62,200 @@ public class MPJWTFilter implements Filter {
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
- final Optional<Map.Entry<MPJWTContext.MPJWTConfigKey, MPJWTContext.MPJWTConfigValue>> first =
- MPJWTContext.findFirst(httpServletRequest.getRequestURI());
- if (!first.isPresent()) { // nothing found in the context
- chain.doFilter(request, response);
- return;
- }
+ // now wrap the httpServletRequest and override the principal so CXF can propagate into the SecurityContext
+ try {
+ chain.doFilter(new MPJWTServletRequestWrapper(httpServletRequest, authContextInfo), response);
- // todo get JWT and do validation
- // todo not sure what to do with the realm
+ } catch (final Exception e) {
+ // this is an alternative to the @Provider bellow which requires registration on the fly
+ // or users to add it into their webapp for scanning or into the Application itself
+ if (MPJWTException.class.isInstance(e)) {
+ final MPJWTException jwtException = MPJWTException.class.cast(e);
+ HttpServletResponse.class.cast(response).sendError(jwtException.getStatus(), jwtException.getMessage());
+ }
- final String authorizationHeader = ((HttpServletRequest) request).getHeader("Authorization");
- if (authorizationHeader == null || authorizationHeader.isEmpty()) {
- HttpServletResponse.class.cast(response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
- return;
- }
+ if (MPJWTException.class.isInstance(e.getCause())) {
+ final MPJWTException jwtException = MPJWTException.class.cast(e.getCause());
+ HttpServletResponse.class.cast(response).sendError(jwtException.getStatus(), jwtException.getMessage());
+ }
- if (!authorizationHeader.toLowerCase(Locale.ENGLISH).startsWith("bearer ")) {
- HttpServletResponse.class.cast(response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
- return;
}
- final String token = authorizationHeader.substring("bearer ".length());
- final JsonWebToken jsonWebToken;
- try {
- jsonWebToken = validate(token);
+ }
- } catch (final ParseException e) {
- // todo is this enough?
- HttpServletResponse.class.cast(response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
- return;
- }
+ @Override
+ public void destroy() {
- // associate with the producer. Should not be needed.
- // todo We should be able to retrieve it based on the HTTP Servlet Request in the producer
- MPJWTProducer.setJWTPrincipal(jsonWebToken);
+ }
- // now wrap the httpServletRequest and override the principal so CXF can propagate into the SecurityContext
- chain.doFilter(new HttpServletRequestWrapper(httpServletRequest) {
+ private static Function<HttpServletRequest, JsonWebToken> token(final HttpServletRequest httpServletRequest, final JWTAuthContextInfo authContextInfo) {
+
+ return new Function<HttpServletRequest, JsonWebToken>() {
+
+ private JsonWebToken jsonWebToken;
@Override
- public Principal getUserPrincipal() {
+ public JsonWebToken apply(final HttpServletRequest request) {
+
+ // not sure it's worth having synchronization inside a single request
+ // worth case, we would parse and validate the token twice
+ if (jsonWebToken != null) {
+ return jsonWebToken;
+ }
+
+ final String authorizationHeader = httpServletRequest.getHeader("Authorization");
+ if (authorizationHeader == null || authorizationHeader.isEmpty()) {
+ throw new MissingAuthorizationHeaderException();
+ }
+
+ if (!authorizationHeader.toLowerCase(Locale.ENGLISH).startsWith("bearer ")) {
+ throw new BadAuthorizationPrefixException(authorizationHeader);
+ }
+
+ final String token = authorizationHeader.substring("bearer ".length());
+ try {
+ jsonWebToken = validate(token, authContextInfo);
+
+ } catch (final ParseException e) {
+ throw new InvalidTokenException(token, e);
+ }
+
return jsonWebToken;
- }
- @Override
- public boolean isUserInRole(String role) {
- return jsonWebToken.getGroups().contains(role);
}
+ };
- @Override
- public String getAuthType() {
- return "MP-JWT";
- }
+ }
+
+ private static JsonWebToken validate(final String bearerToken, final JWTAuthContextInfo authContextInfo) throws ParseException {
+ JWTCallerPrincipalFactory factory = JWTCallerPrincipalFactory.instance();
+ return factory.parse(bearerToken, authContextInfo);
+ }
+
+ public static class MPJWTServletRequestWrapper extends HttpServletRequestWrapper {
+
+ private final Function<HttpServletRequest, JsonWebToken> tokenFunction;
+ private final HttpServletRequest request;
+
+ /**
+ * Constructs a request object wrapping the given request.
+ *
+ * @param request The request to wrap
+ * @param authContextInfo the context configuration to validate the token
+ * @throws IllegalArgumentException if the request is null
+ */
+ public MPJWTServletRequestWrapper(final HttpServletRequest request, final JWTAuthContextInfo authContextInfo) {
+ super(request);
+ this.request = request;
+ tokenFunction = token(request, authContextInfo);
+
+ // this is so that the MPJWTProducer can find the function and apply it if necessary
+ request.setAttribute(JsonWebToken.class.getName(), tokenFunction);
+ request.setAttribute("javax.security.auth.subject.callable", new Callable<Subject>() {
+ @Override
+ public Subject call() throws Exception {
+ final Set<Principal> principals = new LinkedHashSet<Principal>();
+ final JsonWebToken namePrincipal = tokenFunction.apply(request);
+ principals.add(namePrincipal);
+ principals.addAll(namePrincipal.getGroups().stream().map(role -> (Principal) () -> role).collect(Collectors.toList()));
+ return new Subject(true, principals, Collections.emptySet(), Collections.emptySet());
+ }
+ });
+ }
+
+ @Override
+ public Principal getUserPrincipal() {
+ return tokenFunction.apply(request);
+ }
- }, response);
+ @Override
+ public boolean isUserInRole(String role) {
+ final JsonWebToken jsonWebToken = tokenFunction.apply(request);
+ return jsonWebToken.getGroups().contains(role);
+ }
+ @Override
+ public String getAuthType() {
+ return "MP-JWT";
+ }
}
- @Override
- public void destroy() {
+ private static abstract class MPJWTException extends RuntimeException {
+
+ public MPJWTException() {
+ super();
+ }
+
+ public MPJWTException(final Throwable cause) {
+ super(cause);
+ }
+ public abstract int getStatus();
+
+ public abstract String getMessage();
}
- protected JsonWebToken validate(String bearerToken) throws ParseException {
- JWTCallerPrincipalFactory factory = JWTCallerPrincipalFactory.instance();
- return factory.parse(bearerToken, authContextInfo);
+ private static class MissingAuthorizationHeaderException extends MPJWTException {
+
+ @Override
+ public int getStatus() {
+ return HttpServletResponse.SC_UNAUTHORIZED;
+ }
+
+ @Override
+ public String getMessage() {
+ return "No authorization header provided. Can't validate the JWT.";
+ }
}
+ private static class BadAuthorizationPrefixException extends MPJWTException {
+
+ private String authorizationHeader;
+
+ public BadAuthorizationPrefixException(final String authorizationHeader) {
+ this.authorizationHeader = authorizationHeader;
+ }
+
+ @Override
+ public int getStatus() {
+ return HttpServletResponse.SC_UNAUTHORIZED;
+ }
+
+ @Override
+ public String getMessage() {
+ return "Authorization header does not use the Bearer prefix. Can't validate header " + authorizationHeader;
+ }
+ }
+
+ private static class InvalidTokenException extends MPJWTException {
+
+ private final String token;
+
+ public InvalidTokenException(final String token, final Throwable cause) {
+ super(cause);
+ this.token = token;
+ }
+
+ @Override
+ public int getStatus() {
+ return HttpServletResponse.SC_UNAUTHORIZED;
+ }
+
+ @Override
+ public String getMessage() {
+ return "Invalid or not parsable JWT " + token; // we might want to break down the exceptions so we can have more messages.
+ }
+ }
+
+ @Provider // would be the ideal but not automatically registered
+ public static class MPJWTExceptionMapper implements ExceptionMapper<MPJWTException> {
+
+ @Override
+ public Response toResponse(final MPJWTException exception) {
+ return Response.status(exception.getStatus()).entity(exception.getMessage()).build();
+ }
+
+ }
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/893525f8/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
index 28a1735..bf64601 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
@@ -23,7 +23,6 @@ import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.HandlesTypes;
-import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import java.util.Set;
@@ -51,23 +50,11 @@ public class MPJWTInitializer implements ServletContainerInitializer {
continue; // do we really want Application?
}
- final ApplicationPath applicationPath = clazz.getAnnotation(ApplicationPath.class);
-
final FilterRegistration.Dynamic mpJwtFilter = ctx.addFilter("mp-jwt-filter", MPJWTFilter.class);
mpJwtFilter.setAsyncSupported(true);
mpJwtFilter.addMappingForUrlPatterns(null, false, "/*");
- MPJWTContext.addMapping(
- new MPJWTContext.MPJWTConfigKey(
- ctx.getContextPath(),
- // todo instead of empty path, we need to look for default value
- applicationPath == null ? "" : applicationPath.value()),
-
- new MPJWTContext.MPJWTConfigValue(
- loginConfig.authMethod(),
- loginConfig.realmName())
- );
-
+ break; // no need to add it more than once
}
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/893525f8/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
index 0d3488a..513e271 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
@@ -22,8 +22,10 @@ import org.eclipse.microprofile.jwt.Claims;
import org.eclipse.microprofile.jwt.JsonWebToken;
import javax.enterprise.context.Dependent;
+import javax.enterprise.context.RequestScoped;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.Instance;
+import javax.enterprise.inject.Vetoed;
import javax.enterprise.inject.spi.Annotated;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
@@ -49,6 +51,7 @@ import java.util.Optional;
import java.util.Set;
import java.util.logging.Logger;
+@Vetoed
public class ClaimBean<T> implements Bean<T>, PassivationCapable {
private static Logger logger = Logger.getLogger(MPJWTCDIExtension.class.getName());
@@ -62,10 +65,14 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
@Inject
private Jsonb jsonb;
+ @Inject
+ private JsonWebToken jsonWebToken;
+
private final BeanManager bm;
private final Class rawType;
private final Set<Type> types;
private final String id;
+ private final Class<? extends Annotation> scope;
public ClaimBean(final BeanManager bm, final Type type) {
this.bm = bm;
@@ -73,6 +80,7 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
types.add(type);
rawType = getRawType(type);
this.id = "ClaimBean_" + types;
+ scope = Dependent.class;
}
private Class getRawType(final Type type) {
@@ -84,8 +92,6 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
return (Class) paramType.getRawType();
}
- // todo deal with Optional here? aka check type again
-
throw new UnsupportedOperationException("Unsupported type " + type);
}
@@ -122,7 +128,7 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
@Override
public Class<? extends Annotation> getScope() {
- return Dependent.class;
+ return scope;
}
@Override
@@ -156,7 +162,6 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
final Claim claim = annotated.getAnnotation(Claim.class);
final String key = getClaimKey(claim);
- System.out.println(String.format("Found Claim injection with name=%s and for InjectionPoint=%s", key, ip.toString()));
logger.finest(String.format("Found Claim injection with name=%s and for %s", key, ip.toString()));
if (annotated.getBaseType() instanceof ParameterizedType) {
@@ -190,20 +195,28 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
final ClaimValueWrapper claimValueWrapper = new ClaimValueWrapper(key);
if (claimValueType instanceof ParameterizedType && isOptional((ParameterizedType) claimValueType)) {
- final T claimValue = getClaimValue(key);
- claimValueWrapper.setValue(Optional.ofNullable(claimValue));
+ claimValueWrapper.setValue(() -> {
+ final T claimValue = getClaimValue(key);
+ return Optional.ofNullable(claimValue);
+ });
} else if (claimValueType instanceof ParameterizedType && isSet((ParameterizedType) claimValueType)) {
- final T claimValue = getClaimValue(key);
- claimValueWrapper.setValue(claimValue); // todo convert to set
+ claimValueWrapper.setValue(() -> {
+ final T claimValue = getClaimValue(key);
+ return claimValue;
+ });
} else if (claimValueType instanceof ParameterizedType && isList((ParameterizedType) claimValueType)) {
- final T claimValue = getClaimValue(key);
- claimValueWrapper.setValue(claimValue); // // todo convert to list
+ claimValueWrapper.setValue(() -> {
+ final T claimValue = getClaimValue(key);
+ return claimValue;
+ });
} else if (claimValueType instanceof Class) {
- final T claimValue = getClaimValue(key);
- claimValueWrapper.setValue(claimValue);
+ claimValueWrapper.setValue(() -> {
+ final T claimValue = getClaimValue(key);
+ return claimValue;
+ });
} else {
throw new IllegalArgumentException("Unsupported ClaimValue type " + claimValueType.toString());
@@ -245,13 +258,16 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
}
private T getClaimValue(final String name) {
- final JsonWebToken jwt = MPJWTProducer.getJWTPrincipal();
- if (jwt == null) {
+ final Bean<?> bean = bm.resolve(bm.getBeans(JsonWebToken.class));
+ if (RequestScoped.class.equals(bean.getScope())) {
+ jsonWebToken = JsonWebToken.class.cast(bm.getReference(bean, JsonWebToken.class, null));
+ }
+ if (jsonWebToken == null || !bean.getScope().equals(RequestScoped.class)) {
logger.warning(String.format("Can't retrieve claim %s. No active principal.", name));
return null;
}
- final Optional<T> claimValue = jwt.claim(name);
+ final Optional<T> claimValue = jsonWebToken.claim(name);
logger.finest(String.format("Found ClaimValue=%s for name=%s", claimValue, name));
return claimValue.orElse(null);
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/893525f8/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java
index e0aa68f..a5a4bb5 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueWrapper.java
@@ -18,12 +18,14 @@ package org.apache.tomee.microprofile.jwt.cdi;
import org.eclipse.microprofile.jwt.ClaimValue;
+import java.util.function.Supplier;
+
public class ClaimValueWrapper<T> implements ClaimValue<T> {
private final String name;
- private T value;
+ private Supplier<T> value;
- public ClaimValueWrapper(String name) {
+ public ClaimValueWrapper(final String name) {
this.name = name;
}
@@ -34,10 +36,10 @@ public class ClaimValueWrapper<T> implements ClaimValue<T> {
@Override
public T getValue() {
- return value;
+ return value.get();
}
- public void setValue(T value) {
+ void setValue(final Supplier<T> value) {
this.value = value;
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/893525f8/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java
index 297dfb3..a0434ef 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonbProducer.java
@@ -25,6 +25,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
@ApplicationScoped
+// todo add a qualifier here so we isolate our instance from what applications would do
public class JsonbProducer {
private static Logger log = Logger.getLogger(MPJWTCDIExtension.class.getName());
http://git-wip-us.apache.org/repos/asf/tomee/blob/893525f8/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
index 21196a8..453dcff 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
@@ -21,23 +21,29 @@ import org.eclipse.microprofile.jwt.JsonWebToken;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Produces;
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
+import java.util.Objects;
+import java.util.function.Function;
@ApplicationScoped
public class MPJWTProducer {
- private static ThreadLocal<JsonWebToken> currentPrincipal = new ThreadLocal<>();
-
- public static void setJWTPrincipal(final JsonWebToken principal) {
- currentPrincipal.set(principal);
- }
-
- public static JsonWebToken getJWTPrincipal() {
- return currentPrincipal.get();
- }
+ @Inject
+ private HttpServletRequest httpServletRequest;
@Produces
@RequestScoped
- JsonWebToken currentPrincipal() {
- return currentPrincipal.get();
+ public JsonWebToken currentPrincipal() {
+ Objects.requireNonNull(httpServletRequest, "HTTP Servlet Request is required to produce a JSonWebToken principal.");
+
+ // not very beatiful, but avoids having the MPJWTFilter setting the request or the principal in a thread local
+ // CDI integration already has one - dunno which approach is the best for now
+ final Object tokenAttribute = httpServletRequest.getAttribute(JsonWebToken.class.getName());
+ if (tokenAttribute != null && Function.class.isInstance(tokenAttribute)) {
+ return (JsonWebToken) Function.class.cast(tokenAttribute).apply(httpServletRequest);
+ }
+
+ return null;
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/893525f8/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWPProviderRegistration.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWPProviderRegistration.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWPProviderRegistration.java
new file mode 100644
index 0000000..29c146e
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWPProviderRegistration.java
@@ -0,0 +1,46 @@
+/*
+ * 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.tomee.microprofile.jwt.jaxrs;
+
+import org.apache.openejb.observer.Observes;
+import org.apache.openejb.server.cxf.rs.event.ExtensionProviderRegistration;
+import org.apache.tomee.microprofile.jwt.MPJWTFilter;
+import org.eclipse.microprofile.auth.LoginConfig;
+
+import javax.servlet.FilterRegistration;
+import javax.servlet.ServletContainerInitializer;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.HandlesTypes;
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+import java.util.Set;
+
+/**
+ * OpenEJB/TomEE hack to register a new provider on the fly
+ * Could be package in tomee only or done in another way
+ *
+ * As soon as Roberto is done with the packaging, we can remove all this
+ */
+public class MPJWPProviderRegistration {
+
+ public void registerProvider(@Observes final ExtensionProviderRegistration event) { // openejb hack to register the provider
+ event.getProviders().add(new MPJWTFilter.MPJWTExceptionMapper());
+ event.getProviders().add(new MPJWTSecurityAnnotationsInterceptorsFeature());
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/893525f8/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptor.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptor.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptor.java
new file mode 100644
index 0000000..60c2599
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptor.java
@@ -0,0 +1,54 @@
+package org.apache.tomee.microprofile.jwt.jaxrs;
+
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.SecurityContext;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.net.HttpURLConnection;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
+public class MPJWTSecurityAnnotationsInterceptor implements ContainerRequestFilter {
+
+ private final javax.ws.rs.container.ResourceInfo resourceInfo;
+ private final ConcurrentMap<Method, Set<String>> rolesAllowed;
+ private final Set<Method> denyAll;
+ private final Set<Method> permitAll;
+
+ public MPJWTSecurityAnnotationsInterceptor(final javax.ws.rs.container.ResourceInfo resourceInfo, final ConcurrentMap<Method, Set<String>> rolesAllowed, final Set<Method> denyAll, final Set<Method> permitAll) {
+ this.resourceInfo = resourceInfo;
+ this.rolesAllowed = rolesAllowed;
+ this.denyAll = denyAll;
+ this.permitAll = permitAll;
+ }
+
+ @Override
+ public void filter(final ContainerRequestContext requestContext) throws IOException {
+ if (permitAll.contains(resourceInfo.getResourceMethod())) {
+ return;
+ }
+
+ if (denyAll.contains(resourceInfo.getResourceMethod())) {
+ forbidden(requestContext);
+ return;
+ }
+
+ final Set<String> roles = rolesAllowed.get(resourceInfo.getResourceMethod());
+ if (roles != null && !roles.isEmpty()) {
+ final SecurityContext securityContext = requestContext.getSecurityContext();
+ for (String role : roles) {
+ if (!securityContext.isUserInRole(role)) {
+ forbidden(requestContext);
+ break;
+ }
+ }
+ }
+
+ }
+
+ private void forbidden(final ContainerRequestContext requestContext) {
+ requestContext.abortWith(Response.status(HttpURLConnection.HTTP_FORBIDDEN).build());
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/893525f8/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptorsFeature.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptorsFeature.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptorsFeature.java
new file mode 100644
index 0000000..5a0a00a
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/jaxrs/MPJWTSecurityAnnotationsInterceptorsFeature.java
@@ -0,0 +1,144 @@
+/*
+ * 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.tomee.microprofile.jwt.jaxrs;
+
+import javax.annotation.security.DenyAll;
+import javax.annotation.security.PermitAll;
+import javax.annotation.security.RolesAllowed;
+import javax.ws.rs.container.DynamicFeature;
+import javax.ws.rs.container.ResourceInfo;
+import javax.ws.rs.core.FeatureContext;
+import javax.ws.rs.ext.Provider;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+@Provider
+public class MPJWTSecurityAnnotationsInterceptorsFeature implements DynamicFeature {
+
+ private final ConcurrentMap<Method, Set<String>> rolesAllowed = new ConcurrentHashMap<>();
+ private final Set<Method> denyAll = new HashSet<>();
+ private final Set<Method> permitAll = new HashSet<>();
+
+ @Override
+ public void configure(final ResourceInfo resourceInfo, final FeatureContext context) {
+
+ final boolean hasSecurity = processSecurityAnnotations(resourceInfo.getResourceClass(), resourceInfo.getResourceMethod());
+
+ if (hasSecurity) {
+ context.register(new MPJWTSecurityAnnotationsInterceptor(resourceInfo, rolesAllowed, denyAll, permitAll));
+ }
+
+ }
+
+ private boolean processSecurityAnnotations(final Class clazz, final Method method) {
+
+ final List<Class<? extends Annotation>[]> classSecurityAnnotations = hasClassLevelAnnotations(clazz,
+ RolesAllowed.class, PermitAll.class, DenyAll.class);
+
+ final List<Class<? extends Annotation>[]> methodSecurityAnnotations = hasMethodLevelAnnotations(method,
+ RolesAllowed.class, PermitAll.class, DenyAll.class);
+
+ if (classSecurityAnnotations.size() == 0 && methodSecurityAnnotations.size() == 0) {
+ return false; // nothing to do
+ }
+
+ /*
+ * Process annotations at the class level
+ */
+ if (classSecurityAnnotations.size() > 1) {
+ // todo error to properly handle
+ }
+
+ if (methodSecurityAnnotations.size() > 1) {
+ // todo proper error handling
+ }
+
+ if (methodSecurityAnnotations.size() == 0) { // no need to deal with class level annotations if the method has some
+ final RolesAllowed classRolesAllowed = (RolesAllowed) clazz.getAnnotation(RolesAllowed.class);
+ final PermitAll classPermitAll = (PermitAll) clazz.getAnnotation(PermitAll.class);
+ final DenyAll classDenyAll = (DenyAll) clazz.getAnnotation(DenyAll.class);
+
+ if (classRolesAllowed != null) {
+ Set<String> roles = new HashSet<String>();
+ final Set<String> previous = rolesAllowed.putIfAbsent(method, roles);
+ if (previous != null) {
+ roles = previous;
+ }
+ roles.addAll(Arrays.asList(classRolesAllowed.value()));
+ }
+
+ if (classPermitAll != null) {
+ permitAll.add(method);
+ }
+
+ if (classDenyAll != null) {
+ denyAll.add(method);
+ }
+ }
+
+ final RolesAllowed mthdRolesAllowed = (RolesAllowed) method.getAnnotation(RolesAllowed.class);
+ final PermitAll mthdPermitAll = (PermitAll) method.getAnnotation(PermitAll.class);
+ final DenyAll mthdDenyAll = (DenyAll) method.getAnnotation(DenyAll.class);
+
+ if (mthdRolesAllowed != null) {
+ Set<String> roles = new HashSet<String>();
+ final Set<String> previous = rolesAllowed.putIfAbsent(method, roles);
+ if (previous != null) {
+ roles = previous;
+ }
+ roles.addAll(Arrays.asList(mthdRolesAllowed.value()));
+ }
+
+ if (mthdPermitAll != null) {
+ permitAll.add(method);
+ }
+
+ if (mthdDenyAll != null) {
+ denyAll.add(method);
+ }
+
+ return true;
+ }
+
+ private List<Class<? extends Annotation>[]> hasClassLevelAnnotations(final Class clazz, final Class<? extends Annotation>... annotationsToCheck) {
+ final List<Class<? extends Annotation>[]> list = new ArrayList<>();
+ for (Class<? extends Annotation> annotationToCheck : annotationsToCheck) {
+ if (clazz.isAnnotationPresent(annotationToCheck)) {
+ list.add(annotationsToCheck);
+ }
+ }
+ return list;
+ }
+
+ private List<Class<? extends Annotation>[]> hasMethodLevelAnnotations(final Method method, final Class<? extends Annotation>... annotationsToCheck) {
+ final List<Class<? extends Annotation>[]> list = new ArrayList<>();
+ for (Class<? extends Annotation> annotationToCheck : annotationsToCheck) {
+ if (method.isAnnotationPresent(annotationToCheck)) {
+ list.add(annotationsToCheck);
+ }
+ }
+ return list;
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/893525f8/tck/mp-jwt-embedded/src/main/resources/META-INF/org.apache.openejb.extension
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/resources/META-INF/org.apache.openejb.extension b/tck/mp-jwt-embedded/src/main/resources/META-INF/org.apache.openejb.extension
new file mode 100644
index 0000000..9734019
--- /dev/null
+++ b/tck/mp-jwt-embedded/src/main/resources/META-INF/org.apache.openejb.extension
@@ -0,0 +1 @@
+org.apache.tomee.microprofile.jwt.jaxrs.MPJWPProviderRegistration
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/893525f8/tck/mp-jwt-embedded/src/test/resources/dev.xml
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/test/resources/dev.xml b/tck/mp-jwt-embedded/src/test/resources/dev.xml
index 3814456..3700a3f 100644
--- a/tck/mp-jwt-embedded/src/test/resources/dev.xml
+++ b/tck/mp-jwt-embedded/src/test/resources/dev.xml
@@ -21,6 +21,7 @@
<!-- The required base JAX-RS and CDI based tests that all MP-JWT implementations
must pass.
-->
+
<test name="base-tests" verbose="10">
<groups>
<define name="base-groups">
@@ -50,8 +51,9 @@
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.ClaimValueInjectionTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.JsonValueInjectionTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.ProviderInjectionTest" />
- <class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.RolesAllowedTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.InvalidTokenTest" />
+ <class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.RolesAllowedTest" />
+ <class name="org.eclipse.microprofile.jwt.tck.container.jaxrs.RolesAllowedTest" />
</classes>
</test>
@@ -73,10 +75,15 @@
</run>
</groups>
<classes>
- <class name="org.eclipse.microprofile.jwt.tck.container.ejb.EjbTest" />
+ <class name="org.eclipse.microprofile.jwt.tck.container.ejb.EjbTest" >
+ <methods>
+ <!-- Excluded cause we never really enforce ACC context for EJB Calls in TomEE -->
+ <exclude name="getSubjectClass"/>
+ </methods>
+ </class>
+
<class name="org.eclipse.microprofile.jwt.tck.container.servlet.ServletTest" />
<class name="org.eclipse.microprofile.jwt.tck.container.jacc.SubjectTest" />
</classes>
</test>
-
</suite>
http://git-wip-us.apache.org/repos/asf/tomee/blob/893525f8/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatSecurityService.java
----------------------------------------------------------------------
diff --git a/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatSecurityService.java b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatSecurityService.java
index 81bffd4..4076ab5 100644
--- a/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatSecurityService.java
+++ b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatSecurityService.java
@@ -39,6 +39,7 @@ import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Set;
import java.util.UUID;
+import java.util.concurrent.Callable;
public class TomcatSecurityService extends AbstractSecurityService {
private static final boolean ONLY_DEFAULT_REALM = "true".equals(SystemInstance.get().getProperty("tomee.realm.only-default", "false"));
@@ -330,4 +331,23 @@ public class TomcatSecurityService extends AbstractSecurityService {
}
}
+ @Override
+ protected SecurityContext getDefaultContext() {
+ final Request request = OpenEJBSecurityListener.requests.get();
+ if (request != null) {
+ final Object subjectCallable = request.getAttribute("javax.security.auth.subject.callable");
+ if (subjectCallable != null && Callable.class.isInstance(subjectCallable)) {
+ // maybe we should check, but it's so specific ...
+ try {
+ final Subject subject = (Subject) Callable.class.cast(subjectCallable).call();
+ return new SecurityContext(subject);
+
+ } catch (final Exception e) {
+ // ignore and let it go to the default implementation
+ }
+ }
+ }
+
+ return super.getDefaultContext();
+ }
}
[24/38] tomee git commit: Cleanup
Posted by jl...@apache.org.
Cleanup
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/92846aee
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/92846aee
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/92846aee
Branch: refs/heads/master
Commit: 92846aee07e5346864ab1eb8da2223cfb50b9802
Parents: 5060806
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Fri Mar 2 10:09:31 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Fri Mar 2 10:09:31 2018 +0100
----------------------------------------------------------------------
.../tomee/microprofile/jwt/cdi/ClaimBean.java | 3 +-
.../jwt/cdi/ClaimInjectionPoint.java | 2 +-
.../microprofile/jwt/cdi/MPJWTProducer.java | 101 +------------------
3 files changed, 4 insertions(+), 102 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/92846aee/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
index ad713dd..10abedf 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
@@ -64,7 +64,6 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
} else if (type instanceof ParameterizedType) {
final ParameterizedType paramType = (ParameterizedType) type;
-
return (Class) paramType.getRawType();
}
@@ -195,7 +194,7 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
}
private T getClaimValue(final String name, final Class clazz) {
- final JsonWebToken jwt = MPJWTProducer.getJWTPrincpal();
+ final JsonWebToken jwt = MPJWTProducer.getJWTPrincipal();
if (jwt == null) {
logger.warning(String.format("Can't retrieve claim %s. No active principal.", name));
return null;
http://git-wip-us.apache.org/repos/asf/tomee/blob/92846aee/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimInjectionPoint.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimInjectionPoint.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimInjectionPoint.java
index a281014..949e36c 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimInjectionPoint.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimInjectionPoint.java
@@ -25,7 +25,7 @@ import java.lang.reflect.Type;
import java.util.Collections;
import java.util.Set;
-class ClaimInjectionPoint implements InjectionPoint{
+class ClaimInjectionPoint implements InjectionPoint {
private final Bean bean;
ClaimInjectionPoint(Bean bean) {
http://git-wip-us.apache.org/repos/asf/tomee/blob/92846aee/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
index 1d83a08..21196a8 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/MPJWTProducer.java
@@ -16,122 +16,25 @@
*/
package org.apache.tomee.microprofile.jwt.cdi;
-import org.eclipse.microprofile.jwt.Claim;
-import org.eclipse.microprofile.jwt.ClaimValue;
-import org.eclipse.microprofile.jwt.Claims;
import org.eclipse.microprofile.jwt.JsonWebToken;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Produces;
-import javax.enterprise.inject.spi.InjectionPoint;
-import javax.inject.Inject;
-import javax.json.Json;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonObject;
-import javax.json.JsonValue;
-import javax.json.bind.Jsonb;
-import java.lang.annotation.Annotation;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Optional;
-import java.util.logging.Logger;
@ApplicationScoped
public class MPJWTProducer {
- @Inject
- private Jsonb jsonb;
-
- private static final String TMP = "tmp";
- private static Logger log = Logger.getLogger(MPJWTProducer.class.getName());
private static ThreadLocal<JsonWebToken> currentPrincipal = new ThreadLocal<>();
- public static void setJWTPrincipal(JsonWebToken principal) {
+ public static void setJWTPrincipal(final JsonWebToken principal) {
currentPrincipal.set(principal);
}
- public static JsonWebToken getJWTPrincpal() {
+ public static JsonWebToken getJWTPrincipal() {
return currentPrincipal.get();
}
- <T> ClaimValue<Optional<T>> generalClaimValueProducer(String name) {
- ClaimValueWrapper<Optional<T>> wrapper = new ClaimValueWrapper<>(name);
- T value = getValue(name, false);
- Optional<T> optValue = Optional.ofNullable(value);
- wrapper.setValue(optValue);
- return wrapper;
- }
-
- JsonValue generalJsonValueProducer(String name) {
- Object value = getValue(name, false);
- JsonValue jsonValue = wrapValue(value);
- return jsonValue;
- }
-
- public <T> T getValue(String name, boolean isOptional) {
- JsonWebToken jwt = getJWTPrincpal();
- if (jwt == null) {
- log.fine(String.format("getValue(%s), null JsonWebToken", name));
- return null;
- }
-
- Optional<T> claimValue = jwt.claim(name);
- if (!isOptional && !claimValue.isPresent()) {
- log.fine(String.format("Failed to find Claim for: %s", name));
- }
- log.fine(String.format("getValue(%s), isOptional=%s, claimValue=%s", name, isOptional, claimValue));
- return claimValue.orElse(null);
- }
-
- JsonObject replaceMap(final Map<String, Object> map) {
- return jsonb.fromJson(jsonb.toJson(map), JsonObject.class);
- }
-
- JsonValue wrapValue(Object value) {
- JsonValue jsonValue = null;
- if (value instanceof JsonValue) {
- // This may already be a JsonValue
- jsonValue = (JsonValue) value;
- } else if (value instanceof String) {
- jsonValue = Json.createObjectBuilder()
- .add(TMP, value.toString())
- .build()
- .getJsonString(TMP);
- } else if (value instanceof Number) {
- Number number = (Number) value;
- if ((number instanceof Long) || (number instanceof Integer)) {
- jsonValue = Json.createObjectBuilder()
- .add(TMP, number.longValue())
- .build()
- .getJsonNumber(TMP);
- } else {
- jsonValue = Json.createObjectBuilder()
- .add(TMP, number.doubleValue())
- .build()
- .getJsonNumber(TMP);
- }
- } else if (value instanceof Boolean) {
- Boolean flag = (Boolean) value;
- jsonValue = flag ? JsonValue.TRUE : JsonValue.FALSE;
- } else if (value instanceof Collection) {
- JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
- Collection list = (Collection) value;
- for (Object element : list) {
- if (element instanceof String) {
- arrayBuilder.add(element.toString());
- } else {
- JsonValue jvalue = wrapValue(element);
- arrayBuilder.add(jvalue);
- }
- }
- jsonValue = arrayBuilder.build();
- } else if (value instanceof Map) {
- jsonValue = replaceMap((Map) value);
- }
- return jsonValue;
- }
-
@Produces
@RequestScoped
JsonWebToken currentPrincipal() {
[21/38] tomee git commit: Better injection support
Posted by jl...@apache.org.
Better injection support
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/2b9950f6
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/2b9950f6
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/2b9950f6
Branch: refs/heads/master
Commit: 2b9950f66edc5ffb845b1400155c0aa2be0e858f
Parents: 1ad96bb
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Tue Feb 27 14:20:49 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Tue Feb 27 14:20:49 2018 +0100
----------------------------------------------------------------------
.../tomee/microprofile/jwt/MPJWTFilter.java | 12 ++++++++++
.../jwt/cdi/ClaimValueProducer.java | 11 ++++++---
.../microprofile/jwt/cdi/JsonValueProducer.java | 1 +
.../jwt/cdi/RawClaimTypeProducer.java | 24 ++++++++++++++++----
.../principal/DefaultJWTCallerPrincipal.java | 2 +-
5 files changed, 41 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/2b9950f6/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
index 752bcda..ebed96d 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTFilter.java
@@ -32,8 +32,10 @@ import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.Principal;
+import java.util.Locale;
import java.util.Map;
import java.util.Optional;
@@ -66,6 +68,16 @@ public class MPJWTFilter implements Filter {
// todo not sure what to do with the realm
final String authorizationHeader = ((HttpServletRequest) request).getHeader("Authorization");
+ if (authorizationHeader == null || authorizationHeader.isEmpty()) {
+ HttpServletResponse.class.cast(response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
+ return;
+ }
+
+ if (!authorizationHeader.toLowerCase(Locale.ENGLISH).startsWith("bearer ")) {
+ HttpServletResponse.class.cast(response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
+ return;
+ }
+
final String token = authorizationHeader.substring("bearer ".length());
final JsonWebToken jsonWebToken;
try {
http://git-wip-us.apache.org/repos/asf/tomee/blob/2b9950f6/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java
index aeed7c8..b0e2e7b 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimValueProducer.java
@@ -47,9 +47,14 @@ public class ClaimValueProducer<T> {
boolean isOptional = false;
if (matchType instanceof ParameterizedType) {
actualType = ((ParameterizedType) matchType).getActualTypeArguments()[0];
- isOptional = matchType.getTypeName().equals(Optional.class.getTypeName());
+
+ if (actualType instanceof ParameterizedType) {
+ isOptional = ParameterizedType.class.cast(actualType).getRawType().getTypeName()
+ .startsWith(Optional.class.getTypeName());
+ }
+
if (isOptional) {
- actualType = ((ParameterizedType) matchType).getActualTypeArguments()[0];
+ actualType = ((ParameterizedType) actualType).getActualTypeArguments()[0];
}
}
@@ -62,7 +67,7 @@ public class ClaimValueProducer<T> {
return returnValue;
}
- String getName(final InjectionPoint ip) {
+ private String getName(final InjectionPoint ip) {
String name = null;
for (Annotation ann : ip.getQualifiers()) {
if (ann instanceof Claim) {
http://git-wip-us.apache.org/repos/asf/tomee/blob/2b9950f6/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonValueProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonValueProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonValueProducer.java
index af15b89..645b41b 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonValueProducer.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/JsonValueProducer.java
@@ -29,6 +29,7 @@ import javax.json.JsonString;
import javax.json.JsonValue;
import java.lang.annotation.Annotation;
import java.util.Optional;
+import java.util.Set;
public class JsonValueProducer {
http://git-wip-us.apache.org/repos/asf/tomee/blob/2b9950f6/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/RawClaimTypeProducer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/RawClaimTypeProducer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/RawClaimTypeProducer.java
index 55b6324..fbc037b 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/RawClaimTypeProducer.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/RawClaimTypeProducer.java
@@ -25,7 +25,9 @@ import javax.enterprise.inject.spi.InjectionPoint;
import javax.inject.Inject;
import javax.inject.Named;
import java.lang.annotation.Annotation;
+import java.util.HashSet;
import java.util.Optional;
+import java.util.Set;
public class RawClaimTypeProducer {
@@ -34,13 +36,26 @@ public class RawClaimTypeProducer {
@Produces
@Claim("")
+ public Set<String> getSetOfString(final InjectionPoint ip) {
+ final String name = getName(ip);
+ ClaimValue<Optional<String>> cv = producer.generalClaimValueProducer(name);
+ Optional<String> value = cv.getValue();
+ if (value.isPresent()) {
+ return new HashSet<String>() {{
+ add(value.get());
+ }};
+ }
+ return null;
+ }
+
+ @Produces
+ @Claim("")
@Named("RawClaimTypeProducer#getValue")
public Object getValue(final InjectionPoint ip) {
String name = getName(ip);
ClaimValue<Optional<Object>> cv = producer.generalClaimValueProducer(name);
Optional<Object> value = cv.getValue();
- Object returnValue = value.orElse(null);
- return returnValue;
+ return value.orElse(null);
}
@Produces
@@ -49,11 +64,10 @@ public class RawClaimTypeProducer {
public Optional getOptionalValue(final InjectionPoint ip) {
String name = getName(ip);
ClaimValue<Optional<Object>> cv = producer.generalClaimValueProducer(name);
- Optional<Object> value = cv.getValue();
- return value;
+ return cv.getValue();
}
- String getName(final InjectionPoint ip) {
+ private String getName(final InjectionPoint ip) {
String name = null;
for (Annotation ann : ip.getQualifiers()) {
if (ann instanceof Claim) {
http://git-wip-us.apache.org/repos/asf/tomee/blob/2b9950f6/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
index 47c6ad3..e077ca4 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
@@ -76,7 +76,7 @@ public class DefaultJWTCallerPrincipal extends JWTCallerPrincipal {
} catch (MalformedClaimException e1) {
}
}
- return audSet;
+ return audSet.isEmpty() ? null : audSet;
}
@Override
[32/38] tomee git commit: Incorporate feedback
Posted by jl...@apache.org.
Incorporate feedback
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/898c8219
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/898c8219
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/898c8219
Branch: refs/heads/master
Commit: 898c82191408443ed262bafb0dff8fa61ece1296
Parents: 9a428e1
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Wed Mar 7 08:57:27 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Wed Mar 7 08:57:27 2018 +0100
----------------------------------------------------------------------
.../microprofile/jwt/MPJWTInitializer.java | 3 +-
.../tomee/microprofile/jwt/cdi/ClaimBean.java | 17 ++-
.../microprofile/jwt/cdi/DefaultLiteral.java | 2 +-
.../principal/DefaultJWTCallerPrincipal.java | 114 +++++++++++--------
4 files changed, 79 insertions(+), 57 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/898c8219/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
index bf64601..fb954a5 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/MPJWTInitializer.java
@@ -36,7 +36,7 @@ public class MPJWTInitializer implements ServletContainerInitializer {
public void onStartup(final Set<Class<?>> classes, final ServletContext ctx) throws ServletException {
if (classes == null || classes.isEmpty()) {
- return; // to REST application having @LoginConfig on it
+ return; // to classes having @LoginConfig on it
}
for (Class<?> clazz : classes) {
@@ -48,6 +48,7 @@ public class MPJWTInitializer implements ServletContainerInitializer {
if (!Application.class.isAssignableFrom(clazz)) {
continue; // do we really want Application?
+ // See https://github.com/eclipse/microprofile-jwt-auth/issues/70 to clarify this point
}
final FilterRegistration.Dynamic mpJwtFilter = ctx.addFilter("mp-jwt-filter", MPJWTFilter.class);
http://git-wip-us.apache.org/repos/asf/tomee/blob/898c8219/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
index 513e271..5f7852f 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/ClaimBean.java
@@ -54,9 +54,9 @@ import java.util.logging.Logger;
@Vetoed
public class ClaimBean<T> implements Bean<T>, PassivationCapable {
- private static Logger logger = Logger.getLogger(MPJWTCDIExtension.class.getName());
+ private static final Logger logger = Logger.getLogger(MPJWTCDIExtension.class.getName());
- private final static Set<Annotation> QUALIFIERS = new HashSet<>();
+ private static final Set<Annotation> QUALIFIERS = new HashSet<>();
static {
QUALIFIERS.add(new ClaimLiteral());
@@ -65,9 +65,6 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
@Inject
private Jsonb jsonb;
- @Inject
- private JsonWebToken jsonWebToken;
-
private final BeanManager bm;
private final Class rawType;
private final Set<Type> types;
@@ -112,8 +109,8 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
}
@Override
- public void destroy(T instance, CreationalContext<T> context) {
-
+ public void destroy(final T instance, final CreationalContext<T> context) {
+ logger.finest("Destroying CDI Bean for type " + types.iterator().next());
}
@Override
@@ -153,9 +150,10 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
@Override
public T create(final CreationalContext<T> context) {
+ logger.finest("Creating CDI Bean for type " + types.iterator().next());
final InjectionPoint ip = (InjectionPoint) bm.getInjectableReference(new ClaimInjectionPoint(this), context);
if (ip == null) {
- throw new IllegalStateException("Could not retrieve InjectionPoint");
+ throw new IllegalStateException("Could not retrieve InjectionPoint for type " + types.iterator().next());
}
final Annotated annotated = ip.getAnnotated();
@@ -259,6 +257,7 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
private T getClaimValue(final String name) {
final Bean<?> bean = bm.resolve(bm.getBeans(JsonWebToken.class));
+ JsonWebToken jsonWebToken = null;
if (RequestScoped.class.equals(bean.getScope())) {
jsonWebToken = JsonWebToken.class.cast(bm.getReference(bean, JsonWebToken.class, null));
}
@@ -277,7 +276,7 @@ public class ClaimBean<T> implements Bean<T>, PassivationCapable {
return wrapValue(claimValue);
}
- private static final String TMP = "tmp"; // todo kill this if possible
+ private static final String TMP = "tmp";
private JsonValue wrapValue(Object value) {
JsonValue jsonValue = null;
http://git-wip-us.apache.org/repos/asf/tomee/blob/898c8219/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/DefaultLiteral.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/DefaultLiteral.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/DefaultLiteral.java
index d741258..a084ea3 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/DefaultLiteral.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/cdi/DefaultLiteral.java
@@ -20,5 +20,5 @@ import javax.enterprise.inject.Default;
import javax.enterprise.util.AnnotationLiteral;
class DefaultLiteral extends AnnotationLiteral<Default> implements Default {
- public static Default INSTANCE = new DefaultLiteral();
+ public static final Default INSTANCE = new DefaultLiteral();
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/898c8219/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
----------------------------------------------------------------------
diff --git a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
index e077ca4..b0d6a42 100644
--- a/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
+++ b/tck/mp-jwt-embedded/src/main/java/org/apache/tomee/microprofile/jwt/principal/DefaultJWTCallerPrincipal.java
@@ -42,10 +42,10 @@ import java.util.logging.Logger;
*/
public class DefaultJWTCallerPrincipal extends JWTCallerPrincipal {
- private static Logger logger = Logger.getLogger(DefaultJWTCallerPrincipal.class.getName());
- private String jwt;
- private String type;
- private JwtClaims claimsSet;
+ private static final Logger logger = Logger.getLogger(DefaultJWTCallerPrincipal.class.getName());
+ private final String jwt;
+ private final String type;
+ private final JwtClaims claimsSet;
/**
* Create the DefaultJWTCallerPrincipal from the parsed JWT token and the extracted principal name
@@ -63,17 +63,19 @@ public class DefaultJWTCallerPrincipal extends JWTCallerPrincipal {
@Override
public Set<String> getAudience() {
- Set<String> audSet = new HashSet<>();
+ final Set<String> audSet = new HashSet<>();
try {
- List<String> audList = claimsSet.getStringListClaimValue("aud");
+ final List<String> audList = claimsSet.getStringListClaimValue("aud");
if (audList != null) {
audSet.addAll(audList);
}
- } catch (MalformedClaimException e) {
+
+ } catch (final MalformedClaimException e) {
try {
- String aud = claimsSet.getStringClaimValue("aud");
+ final String aud = claimsSet.getStringClaimValue("aud");
audSet.add(aud);
- } catch (MalformedClaimException e1) {
+ } catch (final MalformedClaimException e1) {
+ logger.log(Level.FINEST, "Can't retrieve malformed 'aud' claim.", e);
}
}
return audSet.isEmpty() ? null : audSet;
@@ -81,14 +83,15 @@ public class DefaultJWTCallerPrincipal extends JWTCallerPrincipal {
@Override
public Set<String> getGroups() {
- HashSet<String> groups = new HashSet<>();
+ final HashSet<String> groups = new HashSet<>();
try {
- List<String> globalGroups = claimsSet.getStringListClaimValue("groups");
+ final List<String> globalGroups = claimsSet.getStringListClaimValue("groups");
if (globalGroups != null) {
groups.addAll(globalGroups);
}
- } catch (MalformedClaimException e) {
- e.printStackTrace();
+
+ } catch (final MalformedClaimException e) {
+ logger.log(Level.FINEST, "Can't retrieve malformed 'groups' claim.", e);
}
return groups;
}
@@ -119,7 +122,8 @@ public class DefaultJWTCallerPrincipal extends JWTCallerPrincipal {
if (claim == null) {
claim = new Long(0);
}
- } catch (MalformedClaimException e) {
+ } catch (final MalformedClaimException e) {
+ logger.log(Level.FINEST, "Can't retrieve 'updated_at' a malformed claim.", e);
}
break;
case groups:
@@ -177,7 +181,8 @@ public class DefaultJWTCallerPrincipal extends JWTCallerPrincipal {
", allowedOrigins=" + getClaim("allowedOrigins") +
", updatedAt=" + getClaim("updated_at") +
", acr='" + getClaim("acr") + '\'';
- StringBuilder tmp = new StringBuilder(toString);
+
+ final StringBuilder tmp = new StringBuilder(toString);
tmp.append(", groups=[");
for (String group : getGroups()) {
tmp.append(group);
@@ -201,15 +206,17 @@ public class DefaultJWTCallerPrincipal extends JWTCallerPrincipal {
if (claimsSet.hasClaim(Claims.sub_jwk.name())) {
replaceMap(Claims.sub_jwk.name());
}
+
// Handle custom claims
- Set<String> customClaimNames = filterCustomClaimNames(claimsSet.getClaimNames());
+ final Set<String> customClaimNames = filterCustomClaimNames(claimsSet.getClaimNames());
for (String name : customClaimNames) {
- Object claimValue = claimsSet.getClaimValue(name);
- Class claimType = claimValue.getClass();
+ final Object claimValue = claimsSet.getClaimValue(name);
if (claimValue instanceof List) {
replaceList(name);
+
} else if (claimValue instanceof Map) {
replaceMap(name);
+
} else if (claimValue instanceof Number) {
replaceNumber(name);
}
@@ -222,8 +229,8 @@ public class DefaultJWTCallerPrincipal extends JWTCallerPrincipal {
* @param claimNames - the current set of claim names in this token
* @return the possibly empty set of names for non-Claims claims
*/
- private Set<String> filterCustomClaimNames(Collection<String> claimNames) {
- HashSet<String> customNames = new HashSet<>(claimNames);
+ private Set<String> filterCustomClaimNames(final Collection<String> claimNames) {
+ final HashSet<String> customNames = new HashSet<>(claimNames);
for (Claims claim : Claims.values()) {
customNames.remove(claim.name());
}
@@ -235,35 +242,42 @@ public class DefaultJWTCallerPrincipal extends JWTCallerPrincipal {
*
* @param name - claim name
*/
- private void replaceMap(String name) {
+ private void replaceMap(final String name) {
try {
- Map<String, Object> map = claimsSet.getClaimValue(name, Map.class);
- JsonObject jsonObject = replaceMap(map);
+ final Map<String, Object> map = claimsSet.getClaimValue(name, Map.class);
+ final JsonObject jsonObject = replaceMap(map);
claimsSet.setClaim(name, jsonObject);
- } catch (MalformedClaimException e) {
+
+ } catch (final MalformedClaimException e) {
logger.log(Level.WARNING, "replaceMap failure for: " + name, e);
}
}
- private JsonObject replaceMap(Map<String, Object> map) {
- JsonObjectBuilder builder = Json.createObjectBuilder();
+ private JsonObject replaceMap(final Map<String, Object> map) {
+ final JsonObjectBuilder builder = Json.createObjectBuilder();
+
for (Map.Entry<String, Object> entry : map.entrySet()) {
- Object entryValue = entry.getValue();
+ final Object entryValue = entry.getValue();
if (entryValue instanceof Map) {
- JsonObject entryJsonObject = replaceMap((Map<String, Object>) entryValue);
+ final JsonObject entryJsonObject = replaceMap((Map<String, Object>) entryValue);
builder.add(entry.getKey(), entryJsonObject);
+
} else if (entryValue instanceof List) {
- JsonArray array = (JsonArray) wrapValue(entryValue);
+ final JsonArray array = (JsonArray) wrapValue(entryValue);
builder.add(entry.getKey(), array);
+
} else if (entryValue instanceof Long || entryValue instanceof Integer) {
- long lvalue = ((Number) entryValue).longValue();
+ final long lvalue = ((Number) entryValue).longValue();
builder.add(entry.getKey(), lvalue);
+
} else if (entryValue instanceof Double || entryValue instanceof Float) {
- double dvalue = ((Number) entryValue).doubleValue();
- builder.add(entry.getKey(), dvalue);
+ final double value = ((Number) entryValue).doubleValue();
+ builder.add(entry.getKey(), value);
+
} else if (entryValue instanceof Boolean) {
- boolean flag = ((Boolean) entryValue).booleanValue();
+ final boolean flag = ((Boolean) entryValue).booleanValue();
builder.add(entry.getKey(), flag);
+
} else if (entryValue instanceof String) {
builder.add(entry.getKey(), entryValue.toString());
}
@@ -271,36 +285,42 @@ public class DefaultJWTCallerPrincipal extends JWTCallerPrincipal {
return builder.build();
}
- private JsonValue wrapValue(Object value) {
+ private JsonValue wrapValue(final Object value) {
JsonValue jsonValue = null;
if (value instanceof Number) {
- Number number = (Number) value;
+ final Number number = (Number) value;
if ((number instanceof Long) || (number instanceof Integer)) {
jsonValue = Json.createObjectBuilder()
.add("tmp", number.longValue())
.build()
.getJsonNumber("tmp");
+
} else {
jsonValue = Json.createObjectBuilder()
.add("tmp", number.doubleValue())
.build()
.getJsonNumber("tmp");
}
+
} else if (value instanceof Boolean) {
- Boolean flag = (Boolean) value;
+ final Boolean flag = (Boolean) value;
jsonValue = flag ? JsonValue.TRUE : JsonValue.FALSE;
+
} else if (value instanceof List) {
- JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
- List list = (List) value;
+ final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
+ final List list = (List) value;
for (Object element : list) {
if (element instanceof String) {
arrayBuilder.add(element.toString());
+
} else {
JsonValue jvalue = wrapValue(element);
arrayBuilder.add(jvalue);
}
+
}
jsonValue = arrayBuilder.build();
+
}
return jsonValue;
}
@@ -311,22 +331,24 @@ public class DefaultJWTCallerPrincipal extends JWTCallerPrincipal {
*
* @param name - claim name
*/
- private void replaceList(String name) {
+ private void replaceList(final String name) {
try {
- List list = claimsSet.getClaimValue(name, List.class);
- JsonArray array = (JsonArray) wrapValue(list);
+ final List list = claimsSet.getClaimValue(name, List.class);
+ final JsonArray array = (JsonArray) wrapValue(list);
claimsSet.setClaim(name, array);
- } catch (MalformedClaimException e) {
+
+ } catch (final MalformedClaimException e) {
logger.log(Level.WARNING, "replaceList failure for: " + name, e);
}
}
- private void replaceNumber(String name) {
+ private void replaceNumber(final String name) {
try {
- Number number = claimsSet.getClaimValue(name, Number.class);
- JsonNumber jsonNumber = (JsonNumber) wrapValue(number);
+ final Number number = claimsSet.getClaimValue(name, Number.class);
+ final JsonNumber jsonNumber = (JsonNumber) wrapValue(number);
claimsSet.setClaim(name, jsonNumber);
- } catch (MalformedClaimException e) {
+
+ } catch (final MalformedClaimException e) {
logger.log(Level.WARNING, "replaceNumber failure for: " + name, e);
}
}
[03/38] tomee git commit: Try to reset to default
Posted by jl...@apache.org.
Try to reset to default
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/7c7236b8
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/7c7236b8
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/7c7236b8
Branch: refs/heads/master
Commit: 7c7236b84f5d07062721c520207b44abe3cc97d1
Parents: d56dc9e
Author: Jean-Louis Monteiro <je...@gmail.com>
Authored: Tue Feb 20 09:34:27 2018 +0100
Committer: Jean-Louis Monteiro <je...@gmail.com>
Committed: Tue Feb 20 09:34:27 2018 +0100
----------------------------------------------------------------------
.../java/org/apache/openejb/core/security/JwtSecurityTest.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/7c7236b8/container/openejb-core/src/test/java/org/apache/openejb/core/security/JwtSecurityTest.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/test/java/org/apache/openejb/core/security/JwtSecurityTest.java b/container/openejb-core/src/test/java/org/apache/openejb/core/security/JwtSecurityTest.java
index 8708074..ddd92f3 100644
--- a/container/openejb-core/src/test/java/org/apache/openejb/core/security/JwtSecurityTest.java
+++ b/container/openejb-core/src/test/java/org/apache/openejb/core/security/JwtSecurityTest.java
@@ -65,7 +65,8 @@ public class JWTSecurityTest {
public static void afterClass() throws Exception {
OpenEJB.destroy();
System.clearProperty(Context.INITIAL_CONTEXT_FACTORY);
- Security.setProperty("login.configuration.provider", null);
+ // unfortunate we can't reset the value, so setting to default (See Configuration)
+ Security.setProperty("login.configuration.provider", "sun.security.provider.ConfigFile");
}
private Assembler configureAssembler(final String defaultUser) throws Exception {