Repository: cxf
Updated Branches:
  refs/heads/master 4fb4de764 -> 2ef6f5840


Adding JWT token related utility code


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/2ef6f584
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/2ef6f584
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/2ef6f584

Branch: refs/heads/master
Commit: 2ef6f584022b7672df00a883525dc58807ffe7d7
Parents: 4fb4de7
Author: Sergey Beryozkin <sberyoz...@talend.com>
Authored: Wed Dec 10 17:04:30 2014 +0000
Committer: Sergey Beryozkin <sberyoz...@talend.com>
Committed: Wed Dec 10 17:04:30 2014 +0000

----------------------------------------------------------------------
 .../cxf/rs/security/jose/JoseConstants.java     |  2 +
 .../apache/cxf/rs/security/jose/JoseUtils.java  | 31 ++++++++
 .../jose/jaxrs/AbstractJwsWriterProvider.java   | 11 ++-
 .../jose/jaxrs/JwsContainerRequestFilter.java   | 18 +----
 .../jaxrs/JwtAuthenticationClientFilter.java    | 75 ++++++++++++++++++++
 .../jose/jaxrs/JwtAuthenticationFilter.java     | 70 ++++++++++++++++++
 .../cxf/rs/security/jose/jaxrs/Priorities.java  | 15 ++--
 .../jose/jws/NoneJwsSignatureProvider.java      | 55 ++++++++++++++
 .../jose/jwt/AbstractJoseJwtConsumer.java       | 73 +++++++++++++++++++
 .../jose/jwt/AbstractJoseJwtProducer.java       | 58 +++++++++++++++
 .../jwt/AbstactJwtAccessTokenValidator.java     | 63 ++++++++++++++++
 .../oauth2/tokens/jwt/JwtAccessTokenUtils.java  | 38 +---------
 .../oidc/rp/AbstractTokenValidator.java         | 64 +++++++++--------
 13 files changed, 478 insertions(+), 95 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/2ef6f584/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java
 
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java
index 6d95234..b268129 100644
--- 
a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java
+++ 
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java
@@ -76,6 +76,8 @@ public final class JoseConstants {
     public static final String A192GCM_ALGO = "A192GCM";
     public static final String A256GCM_ALGO = "A256GCM";
     
+    public static final String JOSE_CONTEXT_PROPERTY = 
"org.apache.cxf.jose.context";
+    
     private JoseConstants() {
         
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/2ef6f584/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseUtils.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseUtils.java
 
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseUtils.java
index 23f9936..122c3eb 100644
--- 
a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseUtils.java
+++ 
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseUtils.java
@@ -24,12 +24,43 @@ import java.util.List;
 import java.util.Set;
 
 import org.apache.cxf.common.util.crypto.CryptoUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
 
 public final class JoseUtils {
+    
     private JoseUtils() {
         
     }
     
+    public static void setJoseContextProperty(JoseHeaders headers) {    
+        String context = 
(String)JAXRSUtils.getCurrentMessage().get(JoseConstants.JOSE_CONTEXT_PROPERTY);
+        if (context != null) {
+            headers.setHeader(JoseConstants.JOSE_CONTEXT_PROPERTY, context);
+        }
+    }
+    public static void setJoseMessageContextProperty(JoseHeaders headers, 
String value) {    
+        headers.setHeader(JoseConstants.JOSE_CONTEXT_PROPERTY, value);
+        
JAXRSUtils.getCurrentMessage().put(JoseConstants.JOSE_CONTEXT_PROPERTY, value);
+    }
+    public static void setMessageContextProperty(JoseHeaders headers) {    
+        String context = 
(String)headers.getHeader(JoseConstants.JOSE_CONTEXT_PROPERTY);
+        if (context != null) {
+            
JAXRSUtils.getCurrentMessage().put(JoseConstants.JOSE_CONTEXT_PROPERTY, 
context);
+        }
+    }
+    public static void validateRequestContextProperty(JoseHeaders headers) {
+        Object requestContext = 
JAXRSUtils.getCurrentMessage().get(JoseConstants.JOSE_CONTEXT_PROPERTY);
+        Object headerContext = 
headers.getHeader(JoseConstants.JOSE_CONTEXT_PROPERTY);
+        if (requestContext == null && headerContext == null) {
+            return;
+        }
+        if (requestContext == null && headerContext != null
+            || requestContext != null && headerContext == null
+            || !requestContext.equals(headerContext)) {
+            throw new SecurityException();
+        }
+    }
+    
     public static String checkContentType(String contentType, String 
defaultType) {
         if (contentType != null) {
             int paramIndex = contentType.indexOf(';');

http://git-wip-us.apache.org/repos/asf/cxf/blob/2ef6f584/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsWriterProvider.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsWriterProvider.java
 
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsWriterProvider.java
index d281b2e..1fc5bdc 100644
--- 
a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsWriterProvider.java
+++ 
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsWriterProvider.java
@@ -24,14 +24,13 @@ import java.io.OutputStream;
 
 import org.apache.cxf.common.util.StringUtils;
 import org.apache.cxf.helpers.IOUtils;
-import org.apache.cxf.message.Message;
 import org.apache.cxf.rs.security.jose.JoseHeaders;
+import org.apache.cxf.rs.security.jose.JoseUtils;
 import org.apache.cxf.rs.security.jose.jws.JwsCompactProducer;
 import org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider;
 import org.apache.cxf.rs.security.jose.jws.JwsUtils;
 
 public class AbstractJwsWriterProvider {
-    private static final String JWS_CONTEXT_PROPERTY = 
"org.apache.cxf.jws.context";
     private JwsSignatureProvider sigProvider;
     
     public void setSignatureProvider(JwsSignatureProvider signatureProvider) {
@@ -39,6 +38,7 @@ public class AbstractJwsWriterProvider {
     }
     
     protected JwsSignatureProvider getInitializedSigProvider(JoseHeaders 
headers) {
+        setRequestContextProperty(headers);
         if (sigProvider != null) {
             return sigProvider;    
         } 
@@ -46,11 +46,8 @@ public class AbstractJwsWriterProvider {
         headers.setAlgorithm(theSigProvider.getAlgorithm());
         return theSigProvider;
     }
-    protected void setRequestContextProperty(Message m, JoseHeaders headers) { 
   
-        String context = (String)m.getContextualProperty(JWS_CONTEXT_PROPERTY);
-        if (context != null) {
-            headers.setHeader(JWS_CONTEXT_PROPERTY, context);
-        }
+    protected void setRequestContextProperty(JoseHeaders headers) {    
+        JoseUtils.setJoseContextProperty(headers);
     }
     protected void writeJws(JwsCompactProducer p, JwsSignatureProvider 
theSigProvider, OutputStream os) 
         throws IOException {

http://git-wip-us.apache.org/repos/asf/cxf/blob/2ef6f584/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsContainerRequestFilter.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsContainerRequestFilter.java
 
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsContainerRequestFilter.java
index 1b5f5d2..6164b8f 100644
--- 
a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsContainerRequestFilter.java
+++ 
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsContainerRequestFilter.java
@@ -36,7 +36,6 @@ import 
org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier;
 @PreMatching
 @Priority(Priorities.JWS_SERVER_READ_PRIORITY)
 public class JwsContainerRequestFilter extends AbstractJwsReaderProvider 
implements ContainerRequestFilter {
-    private static final String JWS_CONTEXT_PROPERTY = 
"org.apache.cxf.jws.context";
     @Override
     public void filter(ContainerRequestContext context) throws IOException {
         if (HttpMethod.GET.equals(context.getMethod())) {
@@ -48,7 +47,7 @@ public class JwsContainerRequestFilter extends 
AbstractJwsReaderProvider impleme
             context.abortWith(JAXRSUtils.toResponse(400));
             return;
         }
-        validateRequestContextProperty(p);
+        JoseUtils.validateRequestContextProperty(p.getJoseHeaders());
         byte[] bytes = p.getDecodedJwsPayloadBytes();
         context.setEntityStream(new ByteArrayInputStream(bytes));
         context.getHeaders().putSingle("Content-Length", 
Integer.toString(bytes.length));
@@ -58,18 +57,5 @@ public class JwsContainerRequestFilter extends 
AbstractJwsReaderProvider impleme
             context.getHeaders().putSingle("Content-Type", ct);
         }
     }
-    protected void validateRequestContextProperty(JwsCompactConsumer c) {
-        Object requestContext = 
JAXRSUtils.getCurrentMessage().get(JWS_CONTEXT_PROPERTY);
-        Object headerContext = 
c.getJoseHeaders().getHeader(JWS_CONTEXT_PROPERTY);
-        if (requestContext == null && headerContext == null) {
-            return;
-        }
-        if (requestContext == null && headerContext != null
-            || requestContext != null && headerContext == null
-            || !requestContext.equals(headerContext)) {
-            throw new SecurityException();
-        }
-        
-        
-    }
+    
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/2ef6f584/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationClientFilter.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationClientFilter.java
 
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationClientFilter.java
new file mode 100644
index 0000000..d8bd8c2
--- /dev/null
+++ 
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationClientFilter.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.cxf.rs.security.jose.jaxrs;
+
+import java.io.IOException;
+
+import javax.annotation.Priority;
+import javax.ws.rs.Priorities;
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientRequestFilter;
+import javax.ws.rs.core.HttpHeaders;
+
+import org.apache.cxf.common.util.Base64UrlUtility;
+import org.apache.cxf.common.util.crypto.CryptoUtils;
+import org.apache.cxf.configuration.security.AuthorizationPolicy;
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.rs.security.jose.JoseHeaders;
+import org.apache.cxf.rs.security.jose.JoseUtils;
+import org.apache.cxf.rs.security.jose.jwt.AbstractJoseJwtProducer;
+import org.apache.cxf.rs.security.jose.jwt.JwtClaims;
+import org.apache.cxf.rs.security.jose.jwt.JwtToken;
+
+@Priority(Priorities.AUTHENTICATION)
+public class JwtAuthenticationClientFilter extends AbstractJoseJwtProducer 
+    implements ClientRequestFilter {
+
+    @Override
+    public void filter(ClientRequestContext requestContext) throws IOException 
{
+        JwtToken jwt = getJwtToken(requestContext);
+        boolean jweRequired = false;
+        if (jwt == null) {
+            AuthorizationPolicy ap = 
JAXRSUtils.getCurrentMessage().getExchange()
+                
.get(Endpoint.class).getEndpointInfo().getExtensor(AuthorizationPolicy.class);
+            if (ap != null && ap.getUserName() != null) {
+                JwtClaims claims = new JwtClaims();
+                claims.setSubject(ap.getUserName());
+                claims.setClaim("password", ap.getPassword());
+                claims.setIssuedAt(System.currentTimeMillis() / 1000);
+                jwt = new JwtToken(new JoseHeaders(), claims);
+                jweRequired = true;
+            }
+        }
+        if (jwt == null) {
+            throw new SecurityException();
+        }
+        JoseUtils.setJoseMessageContextProperty(jwt.getHeaders(),
+                                                getContextPropertyValue());
+        String data = super.processJwt(jwt, true, jweRequired);
+        requestContext.getHeaders().putSingle(HttpHeaders.AUTHORIZATION, 
+                                              "JWT " + data);
+    }
+    protected JwtToken getJwtToken(ClientRequestContext requestContext) {
+        return (JwtToken)requestContext.getProperty("jwt.token");
+    }
+    protected String getContextPropertyValue() {
+        return 
Base64UrlUtility.encode(CryptoUtils.generateSecureRandomBytes(16));
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/2ef6f584/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationFilter.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationFilter.java
 
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationFilter.java
new file mode 100644
index 0000000..32de426
--- /dev/null
+++ 
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwtAuthenticationFilter.java
@@ -0,0 +1,70 @@
+/**
+ * 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.cxf.rs.security.jose.jaxrs;
+
+import java.io.IOException;
+
+import javax.annotation.Priority;
+import javax.ws.rs.Priorities;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.PreMatching;
+import javax.ws.rs.core.HttpHeaders;
+
+import org.apache.cxf.common.security.SimplePrincipal;
+import org.apache.cxf.common.security.SimpleSecurityContext;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.rs.security.jose.JoseUtils;
+import org.apache.cxf.rs.security.jose.jwt.AbstractJoseJwtConsumer;
+import org.apache.cxf.rs.security.jose.jwt.JwtToken;
+import org.apache.cxf.security.SecurityContext;
+
+@PreMatching
+@Priority(Priorities.AUTHENTICATION)
+public class JwtAuthenticationFilter extends AbstractJoseJwtConsumer 
implements ContainerRequestFilter {
+
+    private boolean jweOnly;
+    
+    @Override
+    public void filter(ContainerRequestContext requestContext) throws 
IOException {
+        String auth = 
requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
+        String[] parts = auth == null ? null : auth.split(" ");
+        if (parts == null || !"JWT".equals(parts[0]) || parts.length != 2) {
+            throw new SecurityException();
+        }
+        JwtToken jwt = super.getJwtToken(parts[1], jweOnly);
+        JoseUtils.setMessageContextProperty(jwt.getHeaders());
+        JAXRSUtils.getCurrentMessage().put(SecurityContext.class, 
+              new SimpleSecurityContext(new JwtPrincipal(jwt)));
+    }
+
+    public void setJweOnly(boolean jweOnly) {
+        this.jweOnly = jweOnly;
+    }
+    public static class JwtPrincipal extends SimplePrincipal {
+        private JwtToken jwt;
+        public JwtPrincipal(JwtToken jwt) {
+            super(jwt.getClaims().getSubject());
+            this.jwt = jwt;
+        }
+        public JwtToken getJwt() {
+            return jwt;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/2ef6f584/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/Priorities.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/Priorities.java
 
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/Priorities.java
index fc48ebc..877ff0c 100644
--- 
a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/Priorities.java
+++ 
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/Priorities.java
@@ -19,12 +19,15 @@
 package org.apache.cxf.rs.security.jose.jaxrs;
 
 public final class Priorities {
-    public static final int JWE_SERVER_READ_PRIORITY = 1000;
-    public static final int JWE_WRITE_PRIORITY = 1000;
-    public static final int JWE_CLIENT_READ_PRIORITY = 1001;
-    public static final int JWS_SERVER_READ_PRIORITY = 1001;
-    public static final int JWS_WRITE_PRIORITY = 1001;
-    public static final int JWS_CLIENT_READ_PRIORITY = 1000;
+    public static final int JWE_SERVER_READ_PRIORITY = 1001;
+    public static final int JWS_SERVER_READ_PRIORITY = 1002;
+    
+    public static final int JWE_WRITE_PRIORITY = 1001;
+    public static final int JWS_WRITE_PRIORITY = 1002;
+    
+    public static final int JWE_CLIENT_READ_PRIORITY = 1002;
+    public static final int JWS_CLIENT_READ_PRIORITY = 1001;
+    
     private Priorities() {
         
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/2ef6f584/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/NoneJwsSignatureProvider.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/NoneJwsSignatureProvider.java
 
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/NoneJwsSignatureProvider.java
new file mode 100644
index 0000000..6226102
--- /dev/null
+++ 
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/NoneJwsSignatureProvider.java
@@ -0,0 +1,55 @@
+/**
+ * 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.cxf.rs.security.jose.jws;
+
+import org.apache.cxf.rs.security.jose.JoseHeaders;
+
+public class NoneJwsSignatureProvider implements JwsSignatureProvider {
+
+    @Override
+    public String getAlgorithm() {
+        return "none";
+    }
+
+    @Override
+    public JwsSignature createJwsSignature(JoseHeaders headers) {
+        return new NoneJwsSignature();
+    }
+
+    @Override
+    public byte[] sign(JoseHeaders headers, byte[] content) {
+        JwsSignature sig = createJwsSignature(headers);
+        sig.update(content, 0, content.length);
+        return sig.sign();
+    }
+    private static class NoneJwsSignature implements JwsSignature {
+
+        @Override
+        public void update(byte[] src, int off, int len) {
+            // complete
+        }
+
+        @Override
+        public byte[] sign() {
+            return new byte[]{};
+        }
+        
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/cxf/blob/2ef6f584/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtConsumer.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtConsumer.java
 
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtConsumer.java
new file mode 100644
index 0000000..34dd60c
--- /dev/null
+++ 
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtConsumer.java
@@ -0,0 +1,73 @@
+/**
+ * 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.cxf.rs.security.jose.jwt;
+
+import org.apache.cxf.rs.security.jose.jwe.JweDecryptionProvider;
+import org.apache.cxf.rs.security.jose.jwe.JweJwtCompactConsumer;
+import org.apache.cxf.rs.security.jose.jwe.JweUtils;
+import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactConsumer;
+import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier;
+import org.apache.cxf.rs.security.jose.jws.JwsUtils;
+
+public abstract class AbstractJoseJwtConsumer {
+    private JweDecryptionProvider jweDecryptor;
+    private JwsSignatureVerifier jwsVerifier;
+    protected JwtToken getJwtToken(String wrappedJwtToken, boolean jweOnly) {
+        JweDecryptionProvider theJweDecryptor = 
getInitializedDecryptionProvider(jweOnly);
+        if (theJweDecryptor != null) {
+            if (jweOnly) {
+                return new 
JweJwtCompactConsumer(wrappedJwtToken).decryptWith(jweDecryptor);    
+            }
+            wrappedJwtToken = 
jweDecryptor.decrypt(wrappedJwtToken).getContentText();
+        } else if (jweOnly) {
+            throw new SecurityException();
+        }
+
+        JwsJwtCompactConsumer jwtConsumer = new 
JwsJwtCompactConsumer(wrappedJwtToken);
+        JwtToken jwt = jwtConsumer.getJwtToken(); 
+        JwsSignatureVerifier theSigVerifier = getInitializedSigVerifier();
+        return validateToken(jwtConsumer, jwt, theSigVerifier);
+    }
+    protected JwtToken validateToken(JwsJwtCompactConsumer consumer, JwtToken 
jwt, JwsSignatureVerifier jws) {
+        if (!consumer.verifySignatureWith(jws)) {
+            throw new SecurityException("Invalid Signature");
+        }
+        return jwt;
+    }
+    public void setJweDecryptor(JweDecryptionProvider jweDecryptor) {
+        this.jweDecryptor = jweDecryptor;
+    }
+
+    public void setJweVerifier(JwsSignatureVerifier theJwsVerifier) {
+        this.jwsVerifier = theJwsVerifier;
+    }
+
+    protected JweDecryptionProvider getInitializedDecryptionProvider(boolean 
jweOnly) {
+        if (jweDecryptor != null) {
+            return jweDecryptor;    
+        } 
+        return JweUtils.loadDecryptionProvider(jweOnly);
+    }
+    protected JwsSignatureVerifier getInitializedSigVerifier() {
+        if (jwsVerifier != null) {
+            return jwsVerifier;    
+        } 
+        return JwsUtils.loadSignatureVerifier(true);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/2ef6f584/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtProducer.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtProducer.java
 
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtProducer.java
new file mode 100644
index 0000000..80318fb
--- /dev/null
+++ 
b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwt/AbstractJoseJwtProducer.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.cxf.rs.security.jose.jwt;
+
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.rs.security.jose.jwe.JweEncryptionProvider;
+import org.apache.cxf.rs.security.jose.jwe.JweUtils;
+import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactProducer;
+import org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider;
+import org.apache.cxf.rs.security.jose.jws.JwsUtils;
+import org.apache.cxf.rs.security.jose.jws.NoneJwsSignatureProvider;
+
+public abstract class AbstractJoseJwtProducer {
+    private JwsSignatureProvider sigProvider;
+    private JweEncryptionProvider encryptionProvider;
+    protected String processJwt(JwtToken jwt, boolean jwsRequired, boolean 
jweRequired) {
+        JwsJwtCompactProducer jws = new JwsJwtCompactProducer(jwt); 
+        JwsSignatureProvider theSigProvider = 
getInitializedSigProvider(jweRequired, jwsRequired);
+        String data = jws.signWith(theSigProvider);
+        JweEncryptionProvider theEncProvider = 
getInitializedEncryptionProvider(jweRequired);
+        if (theEncProvider != null) {
+            data = theEncProvider.encrypt(StringUtils.toBytesUTF8(data), null);
+        }
+        return data;
+    }
+    protected JwsSignatureProvider getInitializedSigProvider(boolean 
jwsRequired, boolean jweRequired) {
+        if (sigProvider != null) {
+            return sigProvider;    
+        } 
+        JwsSignatureProvider theSigProvider = 
JwsUtils.loadSignatureProvider(jwsRequired);
+        if (theSigProvider == null && jweRequired) {
+            return new NoneJwsSignatureProvider();
+        }
+        throw new SecurityException();
+    }
+    protected JweEncryptionProvider getInitializedEncryptionProvider(boolean 
required) {
+        if (encryptionProvider != null) {
+            return encryptionProvider;    
+        }
+        return JweUtils.loadEncryptionProvider(required);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/2ef6f584/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/jwt/AbstactJwtAccessTokenValidator.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/jwt/AbstactJwtAccessTokenValidator.java
 
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/jwt/AbstactJwtAccessTokenValidator.java
new file mode 100644
index 0000000..c0caa7c
--- /dev/null
+++ 
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/jwt/AbstactJwtAccessTokenValidator.java
@@ -0,0 +1,63 @@
+/**
+ * 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.cxf.rs.security.oauth2.tokens.jwt;
+
+import java.util.Collections;
+import java.util.List;
+
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.apache.cxf.jaxrs.ext.MessageContext;
+import org.apache.cxf.rs.security.jose.jwt.AbstractJoseJwtConsumer;
+import org.apache.cxf.rs.security.jose.jwt.JwtToken;
+import org.apache.cxf.rs.security.oauth2.common.AccessTokenValidation;
+import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken;
+import org.apache.cxf.rs.security.oauth2.provider.AccessTokenValidator;
+import org.apache.cxf.rs.security.oauth2.provider.OAuthDataProvider;
+import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
+
+public abstract class AbstactJwtAccessTokenValidator extends 
AbstractJoseJwtConsumer 
+    implements AccessTokenValidator {
+    private OAuthDataProvider dataProvider;
+    
+    @Override
+    public List<String> getSupportedAuthorizationSchemes() {
+        return Collections.singletonList("*");
+    }
+
+    @Override
+    public AccessTokenValidation validateAccessToken(MessageContext mc, 
+                                                     String authScheme,
+                                                     String authSchemeData,
+                                                     MultivaluedMap<String, 
String> extraProps)
+        throws OAuthServiceException {
+        ServerAccessToken at = dataProvider.getAccessToken(authSchemeData);
+        JwtToken token = super.getJwtToken(at.getTokenKey(), false);
+        validateToken(token);
+        return new AccessTokenValidation(at);
+    }
+
+    public void setDataProvider(OAuthDataProvider dataProvider) {
+        this.dataProvider = dataProvider;
+    }
+
+    protected void validateToken(JwtToken jwt) {
+        
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/2ef6f584/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/jwt/JwtAccessTokenUtils.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/jwt/JwtAccessTokenUtils.java
 
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/jwt/JwtAccessTokenUtils.java
index 33e74e4..ddd3c51 100644
--- 
a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/jwt/JwtAccessTokenUtils.java
+++ 
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/jwt/JwtAccessTokenUtils.java
@@ -25,7 +25,6 @@ import javax.crypto.SecretKey;
 
 import org.apache.cxf.common.util.StringUtils;
 import org.apache.cxf.rs.security.jose.JoseConstants;
-import org.apache.cxf.rs.security.jose.JoseHeaders;
 import org.apache.cxf.rs.security.jose.jwa.Algorithm;
 import org.apache.cxf.rs.security.jose.jwe.DirectKeyJweDecryption;
 import org.apache.cxf.rs.security.jose.jwe.JweDecryptionProvider;
@@ -33,10 +32,10 @@ import 
org.apache.cxf.rs.security.jose.jwe.JweEncryptionProvider;
 import org.apache.cxf.rs.security.jose.jwe.JweUtils;
 import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactConsumer;
 import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactProducer;
-import org.apache.cxf.rs.security.jose.jws.JwsSignature;
 import org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider;
 import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier;
 import org.apache.cxf.rs.security.jose.jws.JwsUtils;
+import org.apache.cxf.rs.security.jose.jws.NoneJwsSignatureProvider;
 import org.apache.cxf.rs.security.jose.jwt.JwtClaims;
 import org.apache.cxf.rs.security.jose.jwt.JwtToken;
 import org.apache.cxf.rs.security.jose.jwt.JwtUtils;
@@ -60,7 +59,7 @@ public final class JwtAccessTokenUtils {
                                                   Client client,
                                                   JweEncryptionProvider 
jweEncryption) {
         String jwtString = new JwsJwtCompactProducer(jwt)
-                               .signWith(new NoneSignatureProvider());
+                               .signWith(new NoneJwsSignatureProvider());
         String tokenId = jweEncryption.encrypt(getBytes(jwtString), null);
         return toAccessToken(jwt, client, tokenId);
     }
@@ -128,38 +127,7 @@ public final class JwtAccessTokenUtils {
         // TODO: the issuer is indirectly validated by validating the signature
         // but an extra check can be done
     }
-    private static class NoneSignatureProvider implements JwsSignatureProvider 
{
-
-        @Override
-        public String getAlgorithm() {
-            return "none";
-        }
-
-        @Override
-        public JwsSignature createJwsSignature(JoseHeaders headers) {
-            return new NoneJwsSignature();
-        }
-
-        @Override
-        public byte[] sign(JoseHeaders headers, byte[] content) {
-            // TODO Auto-generated method stub
-            return null;
-        }
-        
-    }
-    private static class NoneJwsSignature implements JwsSignature {
-
-        @Override
-        public void update(byte[] src, int off, int len) {
-            // complete
-        }
-
-        @Override
-        public byte[] sign() {
-            return new byte[]{};
-        }
-        
-    }
+    
     private static byte[] getBytes(String str) {
         return StringUtils.toBytesUTF8(str);
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/2ef6f584/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/AbstractTokenValidator.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/AbstractTokenValidator.java
 
b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/AbstractTokenValidator.java
index 69c54a4..f6e95c6 100644
--- 
a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/AbstractTokenValidator.java
+++ 
b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/AbstractTokenValidator.java
@@ -56,8 +56,11 @@ public abstract class AbstractTokenValidator {
             wrappedJwtToken = 
jweDecryptor.decrypt(wrappedJwtToken).getContentText();
         }
 
-        // validate token signature
-        return getTokenValidateSignature(wrappedJwtToken, idTokenKid);
+        JwsJwtCompactConsumer jwtConsumer = new 
JwsJwtCompactConsumer(wrappedJwtToken);
+        JwtToken jwt = jwtConsumer.getJwtToken(); 
+        JwsSignatureVerifier theSigVerifier = getInitializedSigVerifier(jwt, 
idTokenKid);
+        return validateToken(jwtConsumer, jwt, theSigVerifier);
+        
     }
     
     protected void validateJwtClaims(JwtClaims claims, String clientId, 
boolean validateClaimsAlways) {
@@ -79,33 +82,7 @@ public abstract class AbstractTokenValidator {
         JwtUtils.validateJwtTimeClaims(claims, issuedAtRange, 
validateClaimsAlways);
     }
     
-    protected JwtToken getTokenValidateSignature(String wrappedJwtToken, 
String idTokenKid) {
-        // read id_token into JwtToken
-        JwsJwtCompactConsumer jwtConsumer = new 
JwsJwtCompactConsumer(wrappedJwtToken);
-        JwtToken jwt = jwtConsumer.getJwtToken(); 
-        JwsSignatureVerifier theSigVerifier = getInitializedSigVerifier();
-        if (theSigVerifier != null) {
-            return validateToken(jwtConsumer, jwt, theSigVerifier);
-        }
-        if (jwkSetClient == null) {
-            throw new SecurityException("Provider Jwk Set Client is not 
available");
-        }
-        String keyId = idTokenKid != null ? idTokenKid : 
jwtConsumer.getJwtToken().getHeaders().getKeyId();
-        JsonWebKey key = keyId != null ? keyMap.get(keyId) : null;
-        if (key == null) {
-            JsonWebKeys keys = jwkSetClient.get(JsonWebKeys.class);
-            if (keyId != null) {
-                key = keys.getKey(keyId);
-            } else if (keys.getKeys().size() == 1) {
-                key = keys.getKeys().get(0);
-            }
-            keyMap.putAll(keys.getKeyIdMap());
-        }
-        if (key == null) {
-            throw new SecurityException("JWK key with the key id: \"" + keyId 
+ "\" is not available");
-        }
-        return validateToken(jwtConsumer, jwt, 
JwsUtils.getSignatureVerifier(key));
-    }
+    
     protected JwtToken validateToken(JwsJwtCompactConsumer consumer, JwtToken 
jwt, JwsSignatureVerifier jws) {
         if (!consumer.verifySignatureWith(jws)) {
             throw new SecurityException("Invalid Signature");
@@ -138,10 +115,35 @@ public abstract class AbstractTokenValidator {
         } 
         return JweUtils.loadDecryptionProvider(jweOnly);
     }
-    protected JwsSignatureVerifier getInitializedSigVerifier() {
+    protected JwsSignatureVerifier getInitializedSigVerifier(JwtToken jwt, 
String idTokenKid) {
         if (jwsVerifier != null) {
             return jwsVerifier;    
         } 
-        return JwsUtils.loadSignatureVerifier(false);
+        JwsSignatureVerifier theJwsVerifier = 
JwsUtils.loadSignatureVerifier(false);
+        if (theJwsVerifier != null) {
+            return theJwsVerifier;
+        }
+        if (jwkSetClient == null) {
+            throw new SecurityException("Provider Jwk Set Client is not 
available");
+        }
+        String keyId = idTokenKid != null ? idTokenKid : 
jwt.getHeaders().getKeyId();
+        JsonWebKey key = keyId != null ? keyMap.get(keyId) : null;
+        if (key == null) {
+            JsonWebKeys keys = jwkSetClient.get(JsonWebKeys.class);
+            if (keyId != null) {
+                key = keys.getKey(keyId);
+            } else if (keys.getKeys().size() == 1) {
+                key = keys.getKeys().get(0);
+            }
+            keyMap.putAll(keys.getKeyIdMap());
+        }
+        if (key == null) {
+            throw new SecurityException("JWK key with the key id: \"" + keyId 
+ "\" is not available");
+        }
+        theJwsVerifier = JwsUtils.getSignatureVerifier(key);
+        if (jwkSetClient == null) {
+            throw new SecurityException();
+        }
+        return theJwsVerifier;
     }
 }

Reply via email to