cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From r...@apache.org
Subject [07/33] cxf git commit: [CXF-6692] Adding a local JWT validation handler
Date Sat, 13 Aug 2016 21:30:45 GMT
[CXF-6692] Adding a local JWT validation handler


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

Branch: refs/heads/master-jaxrs-2.1
Commit: 0870a675e0575dc7a5e9a5a5699f1a03e972672d
Parents: d557319
Author: Sergey Beryozkin <sberyozkin@gmail.com>
Authored: Tue Aug 9 16:25:07 2016 +0100
Committer: Sergey Beryozkin <sberyozkin@gmail.com>
Committed: Tue Aug 9 16:25:07 2016 +0100

----------------------------------------------------------------------
 .../filters/LocalJwtAccessTokenValidator.java   | 108 +++++++++++++++++++
 .../provider/AbstractOAuthDataProvider.java     |   2 +-
 .../oauth2/filters/OAuth2JwtFiltersTest.java    |  27 ++++-
 .../oauth2/filters/filters-serverJwt.xml        |  28 ++++-
 4 files changed, 157 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/0870a675/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/filters/LocalJwtAccessTokenValidator.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/filters/LocalJwtAccessTokenValidator.java
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/filters/LocalJwtAccessTokenValidator.java
new file mode 100644
index 0000000..3a83b36
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/filters/LocalJwtAccessTokenValidator.java
@@ -0,0 +1,108 @@
+/**
+ * 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.filters;
+
+import java.util.Collections;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.jaxrs.ext.MessageContext;
+import org.apache.cxf.rs.security.jose.jwt.JoseJwtConsumer;
+import org.apache.cxf.rs.security.jose.jwt.JwtClaims;
+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.OAuthPermission;
+import org.apache.cxf.rs.security.oauth2.common.UserSubject;
+import org.apache.cxf.rs.security.oauth2.provider.AccessTokenValidator;
+import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
+import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
+
+public class LocalJwtAccessTokenValidator extends JoseJwtConsumer implements AccessTokenValidator
{
+
+    public List<String> getSupportedAuthorizationSchemes() {
+        return Collections.singletonList(OAuthConstants.BEARER_AUTHORIZATION_SCHEME);
+    }
+
+    public AccessTokenValidation validateAccessToken(MessageContext mc,
+                                                     String authScheme, 
+                                                     String authSchemeData,
+                                                     MultivaluedMap<String, String>
extraProps) 
+        throws OAuthServiceException {
+        try {
+            JwtToken token = super.getJwtToken(authSchemeData);
+            return convertClaimsToValidation(token.getClaims());
+        } catch (Exception ex) {
+            throw new OAuthServiceException(ex);
+        }
+    }
+
+
+    private AccessTokenValidation convertClaimsToValidation(JwtClaims claims) {
+        AccessTokenValidation atv = new AccessTokenValidation();
+        atv.setInitialValidationSuccessful(true);
+        if (claims.getAudience() != null) {
+            atv.setClientId(claims.getAudience());
+        }
+        if (claims.getIssuedAt() != null) {
+            atv.setTokenIssuedAt(claims.getIssuedAt());
+        } else {
+            atv.setTokenIssuedAt(new Date().getTime());
+        }
+        if (claims.getExpiryTime() != null) {
+            atv.setTokenLifetime(claims.getExpiryTime() - atv.getTokenIssuedAt());
+        }
+        Object resourceAud = claims.getClaim("resource");
+        if (resourceAud != null) {
+            atv.setAudiences(resourceAud instanceof List ? CastUtils.cast((List<?>)resourceAud)

+                : Collections.<String>singletonList((String)resourceAud));
+        }
+        if (claims.getIssuer() != null) {
+            atv.setTokenIssuer(claims.getIssuer());
+        }
+        Object scope = claims.getClaim("scope");
+        if (scope != null) {
+            String[] scopes = scope instanceof String 
+                ? scope.toString().split(" ") : CastUtils.cast((List<?>)scope).toArray(new
String[]{});
+            List<OAuthPermission> perms = new LinkedList<OAuthPermission>();
+            for (String s : scopes) {    
+                if (!StringUtils.isEmpty(s)) {
+                    perms.add(new OAuthPermission(s.trim()));
+                }
+            }
+            atv.setTokenScopes(perms);
+        }
+        String username = (String)claims.getClaim("preferred_username");
+        if (username != null) {
+            UserSubject userSubject = new UserSubject(username);
+            if (claims.getSubject() != null) {
+                userSubject.setId(claims.getSubject());
+            }
+            atv.setTokenSubject(userSubject);
+        } else if (claims.getSubject() != null) {
+            atv.setTokenSubject(new UserSubject(claims.getSubject()));
+        }
+        return atv;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/0870a675/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthDataProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthDataProvider.java
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthDataProvider.java
index e25fcb7..778bd69 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthDataProvider.java
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthDataProvider.java
@@ -115,7 +115,7 @@ public abstract class AbstractOAuthDataProvider implements OAuthDataProvider,
Cl
                             OAuthUtils.convertPermissionsToScopeList(at.getScopes()));
         }
         // OAuth2 resource indicators (resource server audience)
-        if (at.getAudiences().isEmpty()) {
+        if (!at.getAudiences().isEmpty()) {
             List<String> resourceAudiences = at.getAudiences();
             claims.setClaim("resource", 
                             resourceAudiences.size() == 1 ? resourceAudiences.get(0) : resourceAudiences);

http://git-wip-us.apache.org/repos/asf/cxf/blob/0870a675/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/filters/OAuth2JwtFiltersTest.java
----------------------------------------------------------------------
diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/filters/OAuth2JwtFiltersTest.java
b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/filters/OAuth2JwtFiltersTest.java
index 98ba853..02acacc 100644
--- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/filters/OAuth2JwtFiltersTest.java
+++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/filters/OAuth2JwtFiltersTest.java
@@ -50,7 +50,16 @@ public class OAuth2JwtFiltersTest extends AbstractBusClientServerTestBase
{
                    launchServer(BookServerOAuth2ServiceJwt.class, true));
     }
     @org.junit.Test
-    public void testServiceWithJwtTokenAndScope() throws Exception {
+    public void testServiceWithJwtToken() throws Exception {
+        String rsAddress = "https://localhost:" + PORT + "/secured/bookstore/books";
+        doTestServiceWithJwtTokenAndScope(rsAddress);
+    }
+    @org.junit.Test
+    public void testServiceWithJwtTokenAndLocalValidation() throws Exception {
+        String rsAddress = "https://localhost:" + PORT + "/securedLocalValidation/bookstore/books";
+        doTestServiceWithJwtTokenAndScope(rsAddress);
+    }
+    private void doTestServiceWithJwtTokenAndScope(String rsAddress) throws Exception {
         URL busFile = OAuth2JwtFiltersTest.class.getResource("client.xml");
         
         // Get Authorization Code
@@ -84,8 +93,7 @@ public class OAuth2JwtFiltersTest extends AbstractBusClientServerTestBase
{
         assertEquals("consumer-id", claims.getAudience());
         assertEquals("alice", claims.getSubject());
         // Now invoke on the service with the access token
-        String address = "https://localhost:" + PORT + "/secured/bookstore/books";
-        WebClient client = WebClient.create(address, OAuth2TestUtils.setupProviders(),
+        WebClient client = WebClient.create(rsAddress, OAuth2TestUtils.setupProviders(),
                                             busFile.toString());
         client.header("Authorization", "Bearer " + accessToken.getTokenKey());
         
@@ -96,4 +104,17 @@ public class OAuth2JwtFiltersTest extends AbstractBusClientServerTestBase
{
         assertEquals(returnedBook.getName(), "book");
         assertEquals(returnedBook.getId(), 123L);
     }
+    
+    @org.junit.Test
+    public void testServiceLocalValidationWithNoToken() throws Exception {
+        URL busFile = OAuth2FiltersTest.class.getResource("client.xml");
+        
+        // Now invoke on the service with the faked access token
+        String address = "https://localhost:" + PORT + "/securedLocalValidation/bookstore/books";
+        WebClient client = WebClient.create(address, OAuth2TestUtils.setupProviders(), 
+                                            busFile.toString());
+        
+        Response response = client.post(new Book("book", 123L));
+        assertNotEquals(response.getStatus(), 200);
+    }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/0870a675/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oauth2/filters/filters-serverJwt.xml
----------------------------------------------------------------------
diff --git a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oauth2/filters/filters-serverJwt.xml
b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oauth2/filters/filters-serverJwt.xml
index 0d3077a..9ef8099 100644
--- a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oauth2/filters/filters-serverJwt.xml
+++ b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oauth2/filters/filters-serverJwt.xml
@@ -85,12 +85,12 @@ under the License.
       
    <bean id="tvServiceClient" factory-bean="tvServiceClientFactory" factory-method="createWebClient"/>
  
-   <bean id="tokenValidator" class="org.apache.cxf.rs.security.oauth2.filters.AccessTokenValidatorClient">
+   <bean id="remoteTokenValidator" class="org.apache.cxf.rs.security.oauth2.filters.AccessTokenValidatorClient">
        <property name="tokenValidatorClient" ref="tvServiceClient"/>
    </bean>
      
-   <bean id="oAuthFilter" class="org.apache.cxf.rs.security.oauth2.filters.OAuthRequestFilter">
-       <property name="tokenValidator" ref="tokenValidator"/>
+   <bean id="oAuthFilterRemoteValidation" class="org.apache.cxf.rs.security.oauth2.filters.OAuthRequestFilter">
+       <property name="tokenValidator" ref="remoteTokenValidator"/>
    </bean>
    
    <jaxrs:server 
@@ -100,10 +100,30 @@ under the License.
            <ref bean="serviceBean"/>
        </jaxrs:serviceBeans>
        <jaxrs:providers>
-           <ref bean="oAuthFilter"/>
+           <ref bean="oAuthFilterRemoteValidation"/>
        </jaxrs:providers>
    </jaxrs:server>
    
+   <bean id="localTokenValidator" class="org.apache.cxf.rs.security.oauth2.filters.LocalJwtAccessTokenValidator"/>
+     
+   <bean id="oAuthFilterLocalValidation" class="org.apache.cxf.rs.security.oauth2.filters.OAuthRequestFilter">
+       <property name="tokenValidator" ref="localTokenValidator"/>
+   </bean>
+   
+   <jaxrs:server 
+       depends-on="tls-config" 
+       address="https://localhost:${testutil.ports.jaxrs-oauth2-filtersJwt}/securedLocalValidation">
+       <jaxrs:serviceBeans>
+           <ref bean="serviceBean"/>
+       </jaxrs:serviceBeans>
+       <jaxrs:providers>
+           <ref bean="oAuthFilterLocalValidation"/>
+       </jaxrs:providers>
+       <jaxrs:properties>
+            <entry key="rs.security.signature.in.properties" value="org/apache/cxf/systest/jaxrs/security/alice.rs.properties"/>
+       </jaxrs:properties>
+   </jaxrs:server>
+   
    <http:conduit name="https://localhost.*">
         <http:client ConnectionTimeout="3000000" ReceiveTimeout="3000000"/>
         <http:tlsClientParameters disableCNCheck="true">


Mime
View raw message