knox-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lmc...@apache.org
Subject knox git commit: KNOX-609 - Add unit tests for the SSOCookieFederationProvider.
Date Mon, 19 Oct 2015 14:52:37 GMT
Repository: knox
Updated Branches:
  refs/heads/master 501fd7e66 -> d6f6f6efc


KNOX-609 - Add unit tests for the SSOCookieFederationProvider.

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

Branch: refs/heads/master
Commit: d6f6f6efc10b19a487c9101f2f0261f978f19d5e
Parents: 501fd7e
Author: Larry McCay <lmccay@hortonworks.com>
Authored: Mon Oct 19 07:52:26 2015 -0700
Committer: Larry McCay <lmccay@hortonworks.com>
Committed: Mon Oct 19 07:52:26 2015 -0700

----------------------------------------------------------------------
 .../jwt/filter/AccessTokenFederationFilter.java |   9 +-
 .../filter/JWTAccessTokenAssertionFilter.java   |   8 +-
 .../jwt/filter/JWTFederationFilter.java         |   8 +-
 .../jwt/filter/SSOCookieFederationFilter.java   |  24 +-
 .../provider/federation/JWTTokenTest.java       |  33 +-
 .../federation/SSOCookieProviderTest.java       | 551 +++++++++++++++++++
 .../services/security/token/impl/JWT.java       |   4 -
 .../services/security/token/impl/JWTToken.java  |   6 +-
 8 files changed, 609 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/knox/blob/d6f6f6ef/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/AccessTokenFederationFilter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/AccessTokenFederationFilter.java
b/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/AccessTokenFederationFilter.java
index cf2c244..ab29a4d 100644
--- a/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/AccessTokenFederationFilter.java
+++ b/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/AccessTokenFederationFilter.java
@@ -21,6 +21,7 @@ import java.io.IOException;
 import java.security.Principal;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
+import java.text.ParseException;
 import java.util.HashSet;
 import java.util.Set;
 
@@ -63,7 +64,13 @@ public class AccessTokenFederationFilter implements Filter {
     if (header != null && header.startsWith(BEARER)) {
       // what follows the bearer designator should be the JWT token being used to request
or as an access token
       String wireToken = header.substring(BEARER.length());
-      JWTToken token = JWTToken.parseToken(wireToken);
+      JWTToken token;
+      try {
+        token = JWTToken.parseToken(wireToken);
+      } catch (ParseException e) {
+        throw new ServletException("ParseException encountered while processing the JWT token:
", e);
+      }
+
       boolean verified = false;
       try {
         verified = authority.verifyToken(token);

http://git-wip-us.apache.org/repos/asf/knox/blob/d6f6f6ef/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/JWTAccessTokenAssertionFilter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/JWTAccessTokenAssertionFilter.java
b/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/JWTAccessTokenAssertionFilter.java
index 8de9a75..d34c7df 100644
--- a/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/JWTAccessTokenAssertionFilter.java
+++ b/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/JWTAccessTokenAssertionFilter.java
@@ -20,6 +20,7 @@ package org.apache.hadoop.gateway.provider.federation.jwt.filter;
 import java.io.IOException;
 import java.security.AccessController;
 import java.security.Principal;
+import java.text.ParseException;
 import java.util.HashMap;
 
 import javax.security.auth.Subject;
@@ -75,7 +76,12 @@ public class JWTAccessTokenAssertionFilter extends AbstractIdentityAssertionFilt
     if (header != null && header.startsWith(BEARER)) {
       // what follows the bearer designator should be the JWT token being used to request
or as an access token
       String wireToken = header.substring(BEARER.length());
-      JWTToken token = JWTToken.parseToken(wireToken);
+      JWTToken token;
+      try {
+        token = JWTToken.parseToken(wireToken);
+      } catch (ParseException e) {
+        throw new ServletException("ParseException encountered while processing the JWT token:
", e);
+      }
       // ensure that there is a valid jwt token available and that there isn't a misconfiguration
of filters
       if (token != null) {
         try {

http://git-wip-us.apache.org/repos/asf/knox/blob/d6f6f6ef/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/JWTFederationFilter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/JWTFederationFilter.java
b/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/JWTFederationFilter.java
index 67e3a97..48bc51d 100644
--- a/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/JWTFederationFilter.java
+++ b/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/JWTFederationFilter.java
@@ -39,6 +39,7 @@ import java.io.IOException;
 import java.security.Principal;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
+import java.text.ParseException;
 import java.util.HashSet;
 import java.util.Set;
 
@@ -63,7 +64,12 @@ public class JWTFederationFilter implements Filter {
     if (header != null && header.startsWith(BEARER)) {
       // what follows the bearer designator should be the JWT token being used to request
or as an access token
       String wireToken = header.substring(BEARER.length());
-      JWTToken token = JWTToken.parseToken(wireToken);
+      JWTToken token;
+      try {
+        token = JWTToken.parseToken(wireToken);
+      } catch (ParseException e) {
+        throw new ServletException("ParseException encountered while processing the JWT token:
", e);
+      }
       boolean verified = false;
       try {
         verified = authority.verifyToken(token);

http://git-wip-us.apache.org/repos/asf/knox/blob/d6f6f6ef/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java
b/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java
index b36c7a3..e2635b4 100644
--- a/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java
+++ b/gateway-provider-security-jwt/src/main/java/org/apache/hadoop/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java
@@ -21,6 +21,7 @@ import java.io.IOException;
 import java.security.Principal;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
+import java.security.interfaces.RSAPublicKey;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashSet;
@@ -31,6 +32,7 @@ import javax.security.auth.Subject;
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
@@ -49,21 +51,26 @@ import org.apache.hadoop.gateway.services.security.token.impl.JWTToken;
 public class SSOCookieFederationFilter implements Filter {
   private static JWTMessages log = MessagesFactory.get( JWTMessages.class );
   private static final String ORIGINAL_URL_QUERY_PARAM = "originalUrl=";
-  private static final String SSO_COOKIE_NAME = "sso.cookie.name";
-  private static final String SSO_EXPECTED_AUDIENCES = "sso.expected.audiences";
-  private static final String SSO_AUTHENTICATION_PROVIDER_URL = "sso.authentication.provider.url";
+  public static final String SSO_COOKIE_NAME = "sso.cookie.name";
+  public static final String SSO_EXPECTED_AUDIENCES = "sso.expected.audiences";
+  public static final String SSO_AUTHENTICATION_PROVIDER_URL = "sso.authentication.provider.url";
   private static final String DEFAULT_SSO_COOKIE_NAME = "hadoop-jwt";
 
-  private JWTokenAuthority authority = null;
+  protected JWTokenAuthority authority = null;
   private String cookieName = null;
   private List<String> audiences = null;
   private String authenticationProviderUrl = null;
 
   @Override
   public void init( FilterConfig filterConfig ) throws ServletException {
-    GatewayServices services = (GatewayServices) filterConfig.getServletContext().getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
-    authority = (JWTokenAuthority) services.getService(GatewayServices.TOKEN_SERVICE);
-
+    ServletContext context = filterConfig.getServletContext();
+    if (context != null) {
+      GatewayServices services = (GatewayServices) context.getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+      if (services != null) {
+        authority = (JWTokenAuthority) services.getService(GatewayServices.TOKEN_SERVICE);
+      }
+    }
+    
     // configured cookieName
     cookieName = filterConfig.getInitParameter(SSO_COOKIE_NAME);
     if (cookieName == null) {
@@ -80,6 +87,7 @@ public class SSOCookieFederationFilter implements Filter {
     authenticationProviderUrl = filterConfig.getInitParameter(SSO_AUTHENTICATION_PROVIDER_URL);
     if (authenticationProviderUrl == null) {
       log.missingAuthenticationProviderUrlConfiguration();
+      throw new ServletException("Required authentication provider URL is missing.");
     }
   }
 
@@ -192,7 +200,7 @@ public class SSOCookieFederationFilter implements Filter {
     }
     String loginURL = authenticationProviderUrl + delimiter
         + ORIGINAL_URL_QUERY_PARAM
-        + request.getRequestURL().toString() + getOriginalQueryString(request);
+        + request.getRequestURL().append(getOriginalQueryString(request));
     return loginURL;
   }
 

http://git-wip-us.apache.org/repos/asf/knox/blob/d6f6f6ef/gateway-provider-security-jwt/src/test/java/org/apache/hadoop/gateway/provider/federation/JWTTokenTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-jwt/src/test/java/org/apache/hadoop/gateway/provider/federation/JWTTokenTest.java
b/gateway-provider-security-jwt/src/test/java/org/apache/hadoop/gateway/provider/federation/JWTTokenTest.java
index 20aca47..8f5a02a 100644
--- a/gateway-provider-security-jwt/src/test/java/org/apache/hadoop/gateway/provider/federation/JWTTokenTest.java
+++ b/gateway-provider-security-jwt/src/test/java/org/apache/hadoop/gateway/provider/federation/JWTTokenTest.java
@@ -23,33 +23,36 @@ import org.apache.hadoop.gateway.services.security.token.impl.JWTToken;
 import org.junit.Test;
 
 public class JWTTokenTest extends TestCase {
-  private static final String JWT_TOKEN = "eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MjU2NTA1MzksInN1YiI6Imd1ZXN0IiwiYXVkIjoiSFNTTyIsImlzcyI6IkhTU08ifQ.lNLCcDeVpnsksbD_oE4YFKE_0HPLg0Qh0ToQHhzGSUCUNOm_dDRg3mtAHUz4qchwuAnGmZrnOAvY9a1832WMC1qJNjUHv1mxmox3yAneUIyVzZjazZsekdaQWgl7tha1OiE1iUhupXQtCFf7F3J10SsUImiE1F9XAMVIl5ut38c";
+  private static final String JWT_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MTY5MjkxMDksImp0aSI6ImFhN2Y4ZDBhOTVjIiwic2NvcGVzIjpbInJlcG8iLCJwdWJsaWNfcmVwbyJdfQ.XCEwpBGvOLma4TCoh36FU7XhUbcskygS81HE1uHLf0E";
   private static final String HEADER = "{\"alg\":\"RS256\", \"type\":\"JWT\"}";
   private static final String CLAIMS = "{\"iss\": \"gateway\", \"prn\": \"john.doe@example.com\",
\"aud\": \"https://login.example.com\", \"exp\": \"1363360913\"}";
   
-  @Test
-  public void testTokenParsing() throws Exception {
-    JWTToken token = JWTToken.parseToken(JWT_TOKEN);
-    
-    //assertEquals(token.getHeader(), HEADER);
-    //assertEquals(token.getClaims(), CLAIMS);
-    
-//    assertEquals(token.getIssuer(), "gateway");
-//    assertEquals(token.getPrincipal(), "john.doe@example.com");
-//    assertEquals(token.getAudience(), "https://login.example.com");
-//    assertEquals(token.getExpires(), "1363360913");
-  }
+//  public void testTokenParsing() throws Exception {
+//    try {
+//      JWTToken token = JWTToken.parseToken(JWT_TOKEN);
+//      assertEquals(token.getHeader(), HEADER);
+//      assertEquals(token.getClaims(), CLAIMS);
+//      
+//      assertEquals(token.getIssuer(), "gateway");
+//      assertEquals(token.getPrincipal(), "john.doe@example.com");
+//      assertEquals(token.getAudience(), "https://login.example.com");
+//      assertEquals(token.getExpires(), "1363360913");
+//    }
+//    catch (ParseException pe) {
+//      fail("ParseException encountered.");
+//    }
+//  }
   
   @Test 
   public void testTokenCreation() throws Exception {
     String[] claims = new String[4];
-    claims[0] = "3MVG99OxTyEMCQ3gNp2PjkqeZKxnmAiG1xV4oHh9AKL_rSK.BoSVPGZHQukXnVjzRgSuQqGn75NL7yfkQcyy7";
+    claims[0] = "HSSO";
     claims[1] = "john.doe@example.com";
     claims[2] = "https://login.example.com";
     claims[3] = Long.toString( ( System.currentTimeMillis()/1000 ) + 300);
     JWTToken token = new JWTToken("RS256", claims);
 
-    assertEquals(token.getIssuer(), "3MVG99OxTyEMCQ3gNp2PjkqeZKxnmAiG1xV4oHh9AKL_rSK.BoSVPGZHQukXnVjzRgSuQqGn75NL7yfkQcyy7");
+    assertEquals(token.getIssuer(), "HSSO");
     assertEquals(token.getSubject(), "john.doe@example.com");
     assertEquals(token.getAudience(), "https://login.example.com");
   }

http://git-wip-us.apache.org/repos/asf/knox/blob/d6f6f6ef/gateway-provider-security-jwt/src/test/java/org/apache/hadoop/gateway/provider/federation/SSOCookieProviderTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-security-jwt/src/test/java/org/apache/hadoop/gateway/provider/federation/SSOCookieProviderTest.java
b/gateway-provider-security-jwt/src/test/java/org/apache/hadoop/gateway/provider/federation/SSOCookieProviderTest.java
new file mode 100644
index 0000000..cfa1b37
--- /dev/null
+++ b/gateway-provider-security-jwt/src/test/java/org/apache/hadoop/gateway/provider/federation/SSOCookieProviderTest.java
@@ -0,0 +1,551 @@
+/**
+ * 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.hadoop.gateway.provider.federation;
+
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.Principal;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Properties;
+import java.util.Date;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.hadoop.gateway.provider.federation.jwt.filter.SSOCookieFederationFilter;
+import org.apache.hadoop.gateway.security.PrimaryPrincipal;
+import org.apache.hadoop.gateway.services.security.token.JWTokenAuthority;
+import org.apache.hadoop.gateway.services.security.token.TokenServiceException;
+import org.apache.hadoop.gateway.services.security.token.impl.JWT;
+import org.apache.hadoop.gateway.services.security.token.impl.JWTToken;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.nimbusds.jose.*;
+import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.jwt.SignedJWT;
+import com.nimbusds.jose.crypto.RSASSASigner;
+import com.nimbusds.jose.util.Base64URL;
+
+public class SSOCookieProviderTest  {
+  private static final String SERVICE_URL = "https://localhost:8888/resource";
+  private static final String REDIRECT_LOCATION =
+      "https://localhost:8443/authserver?originalUrl=" + SERVICE_URL;
+  RSAPublicKey publicKey = null;
+  RSAPrivateKey privateKey = null;
+  SSOCookieFederationFilter handler = null;
+
+  @Test
+  public void testCustomCookieNameJWT() throws Exception {
+    try {
+      Properties props = getProperties();
+      props.put("sso.cookie.name", "jowt");
+      handler.init(new TestFilterConfig(props));
+
+      SignedJWT jwt = getJWT("alice", new Date(new Date().getTime() + 5000),
+          privateKey);
+
+      Cookie cookie = new Cookie("jowt", jwt.serialize());
+      HttpServletRequest request = EasyMock.createNiceMock(HttpServletRequest.class);
+      EasyMock.expect(request.getCookies()).andReturn(new Cookie[] { cookie });
+      EasyMock.expect(request.getRequestURL()).andReturn(
+          new StringBuffer(SERVICE_URL));
+      EasyMock.expect(request.getQueryString()).andReturn(null);
+      HttpServletResponse response = EasyMock.createNiceMock(HttpServletResponse.class);
+      EasyMock.expect(response.encodeRedirectURL(SERVICE_URL)).andReturn(
+          SERVICE_URL);
+      EasyMock.replay(request);
+
+      ((TestSSOCookieFederationProvider) handler).setTokenService(new TestJWTokenAuthority());
+      TestFilterChain chain = new TestFilterChain();
+      handler.doFilter(request, response, chain);
+      Assert.assertTrue("doFilterCalled should not be false.", chain.doFilterCalled == true);
+      Set<PrimaryPrincipal> principals = chain.subject.getPrincipals(PrimaryPrincipal.class);
+      Assert.assertTrue("No PrimaryPrincipal returned.", principals.size() > 0);
+      Assert.assertEquals("Not the expected principal", "alice", ((Principal)principals.toArray()[0]).getName());
+    } catch (ServletException se) {
+      fail("Should NOT have thrown a ServletException.");
+    }
+  }
+
+  @Test
+  public void testNoProviderURLJWT() throws Exception {
+    try {
+      Properties props = getProperties();
+      props
+          .remove("sso.authentication.provider.url");
+      handler.init(new TestFilterConfig(props));
+
+      fail("Servlet exception should have been thrown.");
+
+    } catch (ServletException se) {
+      // expected - let's ensure it mentions the missing authenticaiton provider URL
+      se.getMessage().contains("authentication provider URL is missing");
+    }
+  }
+/*
+  @Test
+  public void testUnableToParseJWT() throws Exception {
+    try {
+      KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+      kpg.initialize(2048);
+
+      KeyPair kp = kpg.genKeyPair();
+      RSAPublicKey publicKey = (RSAPublicKey) kp.getPublic();
+
+      handler.setPublicKey(publicKey);
+
+      Properties props = getProperties();
+      handler.init(props);
+
+      SignedJWT jwt = getJWT("bob", new Date(new Date().getTime() + 5000),
+          privateKey);
+
+      Cookie cookie = new Cookie("hadoop-jwt", "ljm" + jwt.serialize());
+      HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+      Mockito.when(request.getCookies()).thenReturn(new Cookie[] { cookie });
+      Mockito.when(request.getRequestURL()).thenReturn(
+          new StringBuffer(SERVICE_URL));
+      HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
+      Mockito.when(response.encodeRedirectURL(SERVICE_URL)).thenReturn(
+          SERVICE_URL);
+
+      AuthenticationToken token = handler.alternateAuthenticate(request,
+          response);
+      Mockito.verify(response).sendRedirect(REDIRECT_LOCATION);
+    } catch (ServletException se) {
+      fail("alternateAuthentication should NOT have thrown a ServletException");
+    } catch (AuthenticationException ae) {
+      fail("alternateAuthentication should NOT have thrown a AuthenticationException");
+    }
+  }
+
+  @Test
+  public void testFailedSignatureValidationJWT() throws Exception {
+    try {
+
+      // Create a public key that doesn't match the one needed to
+      // verify the signature - in order to make it fail verification...
+      KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+      kpg.initialize(2048);
+
+      KeyPair kp = kpg.genKeyPair();
+      RSAPublicKey publicKey = (RSAPublicKey) kp.getPublic();
+
+      handler.setPublicKey(publicKey);
+
+      Properties props = getProperties();
+      handler.init(props);
+
+      SignedJWT jwt = getJWT("bob", new Date(new Date().getTime() + 5000),
+          privateKey);
+
+      Cookie cookie = new Cookie("hadoop-jwt", jwt.serialize());
+      HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+      Mockito.when(request.getCookies()).thenReturn(new Cookie[] { cookie });
+      Mockito.when(request.getRequestURL()).thenReturn(
+          new StringBuffer(SERVICE_URL));
+      HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
+      Mockito.when(response.encodeRedirectURL(SERVICE_URL)).thenReturn(
+          SERVICE_URL);
+
+      AuthenticationToken token = handler.alternateAuthenticate(request,
+          response);
+      Mockito.verify(response).sendRedirect(REDIRECT_LOCATION);
+    } catch (ServletException se) {
+      fail("alternateAuthentication should NOT have thrown a ServletException");
+    } catch (AuthenticationException ae) {
+      fail("alternateAuthentication should NOT have thrown a AuthenticationException");
+    }
+  }
+*/
+  @Test
+  public void testExpiredJWT() throws Exception {
+    try {
+      ((TestSSOCookieFederationProvider) handler).setPublicKey(publicKey);
+
+      Properties props = getProperties();
+      handler.init(new TestFilterConfig(props));
+
+      SignedJWT jwt = getJWT("alice", new Date(new Date().getTime() - 1000),
+          privateKey);
+
+      Cookie cookie = new Cookie("hadoop-jwt", jwt.serialize());
+      HttpServletRequest request = EasyMock.createNiceMock(HttpServletRequest.class);
+      EasyMock.expect(request.getCookies()).andReturn(new Cookie[] { cookie });
+      EasyMock.expect(request.getRequestURL()).andReturn(
+          new StringBuffer(SERVICE_URL));
+      EasyMock.expect(request.getQueryString()).andReturn(null);
+      HttpServletResponse response = EasyMock.createNiceMock(HttpServletResponse.class);
+      EasyMock.expect(response.encodeRedirectURL(SERVICE_URL)).andReturn(
+          SERVICE_URL);
+      EasyMock.replay(request);
+
+      ((TestSSOCookieFederationProvider) handler).setTokenService(new TestJWTokenAuthority());
+      TestFilterChain chain = new TestFilterChain();
+      handler.doFilter(request, response, chain);
+      Assert.assertTrue("doFilterCalled should not be false.", chain.doFilterCalled == false);
+//      Set<PrimaryPrincipal> principals = chain.subject.getPrincipals(PrimaryPrincipal.class);
+//      Assert.assertTrue("No PrimaryPrincipal", principals.size() > 0);
+//      Assert.assertEquals("Not the expected principal", "alice", ((Principal)principals.toArray()[0]).getName());
+//      Assert.assertEquals("alice", token.getUserName());
+    } catch (ServletException se) {
+      fail("Should NOT have thrown a ServletException.");
+    }
+  }
+
+
+  @Test
+  public void testInvalidAudienceJWT() throws Exception {
+    try {
+      Properties props = getProperties();
+      props
+          .put("sso.expected.audiences", "foo");
+      handler.init(new TestFilterConfig(props));
+
+      SignedJWT jwt = getJWT("alice", new Date(new Date().getTime() + 5000),
+          privateKey);
+
+      Cookie cookie = new Cookie("hadoop-jwt", jwt.serialize());
+      HttpServletRequest request = EasyMock.createNiceMock(HttpServletRequest.class);
+      EasyMock.expect(request.getCookies()).andReturn(new Cookie[] { cookie });
+      EasyMock.expect(request.getRequestURL()).andReturn(
+          new StringBuffer(SERVICE_URL));
+      EasyMock.expect(request.getQueryString()).andReturn(null);
+      HttpServletResponse response = EasyMock.createNiceMock(HttpServletResponse.class);
+      EasyMock.expect(response.encodeRedirectURL(SERVICE_URL)).andReturn(
+          SERVICE_URL);
+      EasyMock.replay(request);
+
+      ((TestSSOCookieFederationProvider) handler).setTokenService(new TestJWTokenAuthority());
+      TestFilterChain chain = new TestFilterChain();
+      handler.doFilter(request, response, chain);
+      Assert.assertTrue("doFilterCalled should not be false.", chain.doFilterCalled == false);
+      Assert.assertTrue("No Subject should be returned.", chain.subject == null);
+//      Assert.assertEquals("Not the expected principal", "alice", ((Principal)principals.toArray()[0]).getName());
+//      Assert.assertEquals("alice", token.getUserName());
+    } catch (ServletException se) {
+      fail("Should NOT have thrown a ServletException.");
+    }
+  }
+
+  @Test
+  public void testValidAudienceJWT() throws Exception {
+    try {
+      Properties props = getProperties();
+      props
+          .put("sso.expected.audiences", "bar");
+      handler.init(new TestFilterConfig(props));
+
+      SignedJWT jwt = getJWT("alice", new Date(new Date().getTime() + 5000),
+          privateKey);
+
+      Cookie cookie = new Cookie("hadoop-jwt", jwt.serialize());
+      HttpServletRequest request = EasyMock.createNiceMock(HttpServletRequest.class);
+      EasyMock.expect(request.getCookies()).andReturn(new Cookie[] { cookie });
+      EasyMock.expect(request.getRequestURL()).andReturn(
+          new StringBuffer(SERVICE_URL));
+      EasyMock.expect(request.getQueryString()).andReturn(null);
+      HttpServletResponse response = EasyMock.createNiceMock(HttpServletResponse.class);
+      EasyMock.expect(response.encodeRedirectURL(SERVICE_URL)).andReturn(
+          SERVICE_URL);
+      EasyMock.replay(request);
+
+      ((TestSSOCookieFederationProvider) handler).setTokenService(new TestJWTokenAuthority());
+      TestFilterChain chain = new TestFilterChain();
+      handler.doFilter(request, response, chain);
+      Assert.assertTrue("doFilterCalled should not be false.", chain.doFilterCalled == true);
+      Set<PrimaryPrincipal> principals = chain.subject.getPrincipals(PrimaryPrincipal.class);
+      Assert.assertTrue("No PrimaryPrincipal", principals.size() > 0);
+      Assert.assertEquals("Not the expected principal", "alice", ((Principal)principals.toArray()[0]).getName());
+//      Assert.assertEquals("alice", token.getUserName());
+    } catch (ServletException se) {
+      fail("Should NOT have thrown a ServletException.");
+    }
+  }
+
+  @Test
+  public void testValidJWT() throws Exception {
+    try {
+      ((TestSSOCookieFederationProvider) handler).setPublicKey(publicKey);
+
+      Properties props = getProperties();
+      handler.init(new TestFilterConfig(props));
+
+      SignedJWT jwt = getJWT("alice", new Date(new Date().getTime() + 5000),
+          privateKey);
+
+      Cookie cookie = new Cookie("hadoop-jwt", jwt.serialize());
+      HttpServletRequest request = EasyMock.createNiceMock(HttpServletRequest.class);
+      EasyMock.expect(request.getCookies()).andReturn(new Cookie[] { cookie });
+      EasyMock.expect(request.getRequestURL()).andReturn(
+          new StringBuffer(SERVICE_URL));
+      EasyMock.expect(request.getQueryString()).andReturn(null);
+      HttpServletResponse response = EasyMock.createNiceMock(HttpServletResponse.class);
+      EasyMock.expect(response.encodeRedirectURL(SERVICE_URL)).andReturn(
+          SERVICE_URL);
+      EasyMock.replay(request);
+
+      ((TestSSOCookieFederationProvider) handler).setTokenService(new TestJWTokenAuthority());
+      TestFilterChain chain = new TestFilterChain();
+      handler.doFilter(request, response, chain);
+      Assert.assertTrue("doFilterCalled should not be false.", chain.doFilterCalled == true);
+      Set<PrimaryPrincipal> principals = chain.subject.getPrincipals(PrimaryPrincipal.class);
+      Assert.assertTrue("No PrimaryPrincipal", principals.size() > 0);
+      Assert.assertEquals("Not the expected principal", "alice", ((Principal)principals.toArray()[0]).getName());
+//      Assert.assertEquals("alice", token.getUserName());
+    } catch (ServletException se) {
+      fail("Should NOT have thrown a ServletException.");
+    }
+  }
+
+  @Test
+  public void testOrigURLWithQueryString() throws Exception {
+    Properties props = getProperties();
+    handler.init(new TestFilterConfig(props));
+
+    HttpServletRequest request = EasyMock.createNiceMock(HttpServletRequest.class);
+    EasyMock.expect(request.getRequestURL()).andReturn(
+        new StringBuffer(SERVICE_URL));
+    EasyMock.expect(request.getQueryString()).andReturn("name=value");
+    EasyMock.replay(request);
+
+    String loginURL = ((TestSSOCookieFederationProvider)handler).testConstructLoginURL(request);
+    Assert.assertNotNull("loginURL should not be null.", loginURL);
+    Assert.assertEquals("https://localhost:8443/authserver?originalUrl=" + SERVICE_URL +
"?name=value", loginURL);
+  }
+
+  @Test
+  public void testOrigURLNoQueryString() throws Exception {
+    Properties props = getProperties();
+    handler.init(new TestFilterConfig(props));
+
+    HttpServletRequest request = EasyMock.createNiceMock(HttpServletRequest.class);
+    EasyMock.expect(request.getRequestURL()).andReturn(
+        new StringBuffer(SERVICE_URL));
+    EasyMock.expect(request.getQueryString()).andReturn(null);
+    EasyMock.replay(request);
+
+    String loginURL = ((TestSSOCookieFederationProvider)handler).testConstructLoginURL(request);
+    Assert.assertNotNull("LoginURL should not be null.", loginURL);
+    Assert.assertEquals("https://localhost:8443/authserver?originalUrl=" + SERVICE_URL, loginURL);
+  }
+
+  @Before
+  public void setup() throws Exception, NoSuchAlgorithmException {
+    KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+    kpg.initialize(2048);
+
+    KeyPair kp = kpg.genKeyPair();
+    publicKey = (RSAPublicKey) kp.getPublic();
+    privateKey = (RSAPrivateKey) kp.getPrivate();
+
+    handler = new TestSSOCookieFederationProvider();
+  }
+
+  @After
+  public void teardown() throws Exception {
+    handler.destroy();
+  }
+
+  protected Properties getProperties() {
+    Properties props = new Properties();
+    props.setProperty(
+        TestSSOCookieFederationProvider.SSO_AUTHENTICATION_PROVIDER_URL,
+        "https://localhost:8443/authserver");
+    return props;
+  }
+
+  protected SignedJWT getJWT(String sub, Date expires, RSAPrivateKey privateKey)
+      throws Exception {
+    JWTClaimsSet claimsSet = new JWTClaimsSet();
+    claimsSet.setSubject(sub);
+    claimsSet.setIssueTime(new Date(new Date().getTime()));
+    claimsSet.setIssuer("https://c2id.com");
+    claimsSet.setCustomClaim("scope", "openid");
+    claimsSet.setExpirationTime(expires);
+    List<String> aud = new ArrayList<String>();
+    aud.add("bar");
+    claimsSet.setAudience("bar");
+
+    JWSHeader header = new JWSHeader.Builder(JWSAlgorithm.RS256).build();
+
+    SignedJWT signedJWT = new SignedJWT(header, claimsSet);
+    Base64URL sigInput = Base64URL.encode(signedJWT.getSigningInput());
+    JWSSigner signer = new RSASSASigner(privateKey);
+
+    signedJWT.sign(signer);
+
+    return signedJWT;
+  }
+
+  class TestSSOCookieFederationProvider extends SSOCookieFederationFilter {
+    public String testConstructLoginURL(HttpServletRequest req) {
+      return constructLoginURL(req);
+    }
+    
+    public void setPublicKey(RSAPublicKey key) {
+      publicKey = key;
+    }
+    
+    public void setTokenService(JWTokenAuthority ts) {
+      authority = ts;
+    }
+  };
+
+  class TestFilterConfig implements FilterConfig {
+    Properties props = null;
+
+    public TestFilterConfig(Properties props) {
+      this.props = props;
+    }
+
+    @Override
+    public String getFilterName() {
+      return null;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.FilterConfig#getServletContext()
+     */
+    @Override
+    public ServletContext getServletContext() {
+//      JWTokenAuthority authority = EasyMock.createNiceMock(JWTokenAuthority.class);
+//      GatewayServices services = EasyMock.createNiceMock(GatewayServices.class);
+//      EasyMock.expect(services.getService("TokenService").andReturn(authority));
+//      ServletContext context = EasyMock.createNiceMock(ServletContext.class);
+//      EasyMock.expect(context.getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE).andReturn(new
DefaultGatewayServices()));
+      return null;
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.FilterConfig#getInitParameter(java.lang.String)
+     */
+    @Override
+    public String getInitParameter(String name) {
+      return props.getProperty(name, null);
+    }
+
+    /* (non-Javadoc)
+     * @see javax.servlet.FilterConfig#getInitParameterNames()
+     */
+    @Override
+    public Enumeration<String> getInitParameterNames() {
+      return null;
+    }
+    
+  }
+  
+  class TestJWTokenAuthority implements JWTokenAuthority {
+
+    /* (non-Javadoc)
+     * @see org.apache.hadoop.gateway.services.security.token.JWTokenAuthority#issueToken(javax.security.auth.Subject,
java.lang.String)
+     */
+    @Override
+    public JWTToken issueToken(Subject subject, String algorithm)
+        throws TokenServiceException {
+      // TODO Auto-generated method stub
+      return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.hadoop.gateway.services.security.token.JWTokenAuthority#issueToken(java.security.Principal,
java.lang.String)
+     */
+    @Override
+    public JWTToken issueToken(Principal p, String algorithm)
+        throws TokenServiceException {
+      // TODO Auto-generated method stub
+      return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.hadoop.gateway.services.security.token.JWTokenAuthority#issueToken(java.security.Principal,
java.lang.String, java.lang.String)
+     */
+    @Override
+    public JWTToken issueToken(Principal p, String audience, String algorithm)
+        throws TokenServiceException {
+      return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.hadoop.gateway.services.security.token.JWTokenAuthority#verifyToken(org.apache.hadoop.gateway.services.security.token.impl.JWTToken)
+     */
+    @Override
+    public boolean verifyToken(JWTToken token) throws TokenServiceException {
+      return true;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.hadoop.gateway.services.security.token.JWTokenAuthority#issueToken(java.security.Principal,
java.lang.String, java.lang.String, long)
+     */
+    @Override
+    public JWTToken issueToken(Principal p, String audience, String algorithm,
+        long expires) throws TokenServiceException {
+      return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.hadoop.gateway.services.security.token.JWTokenAuthority#issueToken(java.security.Principal,
java.lang.String, long)
+     */
+    @Override
+    public JWT issueToken(Principal p, String audience, long l)
+        throws TokenServiceException {
+      // TODO Auto-generated method stub
+      return null;
+    }
+    
+  }
+  
+  class TestFilterChain implements FilterChain {
+    boolean doFilterCalled = false;
+    Subject subject = null;
+
+    /* (non-Javadoc)
+     * @see javax.servlet.FilterChain#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse)
+     */
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response)
+        throws IOException, ServletException {
+      doFilterCalled = true;
+      
+      subject = Subject.getSubject( AccessController.getContext() );
+    }
+    
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/d6f6f6ef/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/impl/JWT.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/impl/JWT.java
b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/impl/JWT.java
index 4321c0d..b834649 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/impl/JWT.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/impl/JWT.java
@@ -21,10 +21,6 @@ import java.util.Date;
 
 import com.nimbusds.jose.JWSSigner;
 
-/**
- * @author larry
- *
- */
 public interface JWT {
 
   public static final String PRINCIPAL = "prn";

http://git-wip-us.apache.org/repos/asf/knox/blob/d6f6f6ef/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/impl/JWTToken.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/impl/JWTToken.java
b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/impl/JWTToken.java
index 71d5020..7ab05ee 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/impl/JWTToken.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/token/impl/JWTToken.java
@@ -38,14 +38,12 @@ public class JWTToken implements JWT {
 
   SignedJWT jwt = null;
   
-  private JWTToken(byte[] header, byte[] claims, byte[] signature) {
+  private JWTToken(byte[] header, byte[] claims, byte[] signature) throws ParseException
{
     try {
       jwt = new SignedJWT(new Base64URL(new String(header, "UTF8")), new Base64URL(new String(claims,
"UTF8")), 
           new Base64URL(new String(signature, "UTF8")));
     } catch (UnsupportedEncodingException e) {
       log.unsupportedEncoding(e);
-    } catch (ParseException e) {
-      e.printStackTrace();
     }
   }
 
@@ -126,7 +124,7 @@ public class JWTToken implements JWT {
     return b;
   }
 
-  public static JWTToken parseToken(String wireToken) {
+  public static JWTToken parseToken(String wireToken) throws ParseException {
     log.parsingToken(wireToken);
     String[] parts = wireToken.split("\\.");
     JWTToken jwt = new JWTToken(Base64.decodeBase64(parts[0]), Base64.decodeBase64(parts[1]),
Base64.decodeBase64(parts[2]));


Mime
View raw message