You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by mo...@apache.org on 2017/09/25 20:21:12 UTC

[14/22] knox git commit: Merge branch 'master' into KNOX-998-Package_Restructuring

http://git-wip-us.apache.org/repos/asf/knox/blob/b3107e91/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/impl/JWTToken.java
----------------------------------------------------------------------
diff --cc gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/impl/JWTToken.java
index 8b05b4c,0000000..27b1a30
mode 100644,000000..100644
--- a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/impl/JWTToken.java
+++ b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/token/impl/JWTToken.java
@@@ -1,278 -1,0 +1,273 @@@
 +  /**
 +   * 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.knox.gateway.services.security.token.impl;
 +
 +import java.io.UnsupportedEncodingException;
 +import java.text.ParseException;
 +import java.util.Date;
 +import java.util.ArrayList;
 +import java.util.List;
++import java.util.Map;
++
 +import org.apache.commons.codec.binary.Base64;
 +import org.apache.knox.gateway.i18n.messages.MessagesFactory;
 +
 +import com.nimbusds.jose.JOSEException;
 +import com.nimbusds.jose.JWSAlgorithm;
 +import com.nimbusds.jose.JWSHeader;
 +import com.nimbusds.jose.JWSSigner;
 +import com.nimbusds.jose.JWSVerifier;
 +import com.nimbusds.jose.Payload;
 +import com.nimbusds.jose.util.Base64URL;
 +import com.nimbusds.jwt.JWTClaimsSet;
 +import com.nimbusds.jwt.SignedJWT;
 +
 +public class JWTToken implements JWT {
 +  private static JWTProviderMessages log = MessagesFactory.get( JWTProviderMessages.class );
 +
 +  SignedJWT jwt = null;
-   
-   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);
-     }
++
++  private JWTToken(String header, String claims, String signature) throws ParseException {
++    jwt = new SignedJWT(new Base64URL(header), new Base64URL(claims), new Base64URL(signature));
 +  }
 +
 +  public JWTToken(String serializedJWT) throws ParseException {
 +    try {
 +      jwt = SignedJWT.parse(serializedJWT);
 +    } catch (ParseException e) {
 +      log.unableToParseToken(e);
 +      throw e;
 +    }
 +  }
 +
 +  public JWTToken(String alg, String[] claimsArray) {
 +    this(alg, claimsArray, null);
 +  }
 +
 +  public JWTToken(String alg, String[] claimsArray, List<String> audiences) {
 +    JWSHeader header = new JWSHeader(new JWSAlgorithm(alg));
 +
 +    if (claimsArray[2] != null) {
 +      if (audiences == null) {
 +        audiences = new ArrayList<String>();
 +      }
 +      audiences.add(claimsArray[2]);
 +    }
 +    JWTClaimsSet claims = null;
 +    JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder()
 +    .issuer(claimsArray[0])
 +    .subject(claimsArray[1])
 +    .audience(audiences);
 +    if(claimsArray[3] != null) {
 +      builder = builder.expirationTime(new Date(Long.parseLong(claimsArray[3])));
 +    }
-     
++
 +    claims = builder.build();
 +
 +    jwt = new SignedJWT(header, claims);
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see JWT#getPayloadToSign()
 +   */
 +  @Override
 +  public String getHeader() {
 +    JWSHeader header = jwt.getHeader();
 +    return header.toString();
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see JWT#getPayloadToSign()
 +   */
 +  @Override
 +  public String getClaims() {
 +    String c = null;
 +    JWTClaimsSet claims = null;
 +    try {
 +      claims = (JWTClaimsSet) jwt.getJWTClaimsSet();
 +      c = claims.toJSONObject().toJSONString();
 +    } catch (ParseException e) {
 +      log.unableToParseToken(e);
 +    }
 +    return c;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see JWT#getPayloadToSign()
 +   */
 +  @Override
 +  public String getPayload() {
 +    Payload payload = jwt.getPayload();
 +    return payload.toString();
 +  }
 +
 +  public String toString() {
 +    return jwt.serialize();
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see JWT#setSignaturePayload(byte[])
 +   */
 +  @Override
 +  public void setSignaturePayload(byte[] payload) {
 +//    this.payload = payload;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see JWT#getSignaturePayload()
 +   */
 +  @Override
 +  public byte[] getSignaturePayload() {
 +    byte[] b = null;
 +    Base64URL b64 = jwt.getSignature();
 +    if (b64 != null) {
 +      b = b64.decode();
 +    }
 +    return b;
 +  }
 +
 +  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]));
- //    System.out.println("header: " + token.header);
- //    System.out.println("claims: " + token.claims);
- //    System.out.println("payload: " + new String(token.payload));
-     
-     return jwt;
++    return new JWTToken(parts[0], parts[1], parts[2]);
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see JWT#getClaim(java.lang.String)
 +   */
 +  @Override
 +  public String getClaim(String claimName) {
 +    String claim = null;
-     
++
 +    try {
 +      claim = jwt.getJWTClaimsSet().getStringClaim(claimName);
 +    } catch (ParseException e) {
 +      log.unableToParseToken(e);
 +    }
-     
++
 +    return claim;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see JWT#getSubject()
 +   */
 +  @Override
 +  public String getSubject() {
 +    return getClaim(JWT.SUBJECT);
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see JWT#getIssuer()
 +   */
 +  @Override
 +  public String getIssuer() {
 +    return getClaim(JWT.ISSUER);
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see JWT#getAudience()
 +   */
 +  @Override
 +  public String getAudience() {
 +    String[] claim = null;
 +    String c = null;
 +
 +    claim = getAudienceClaims();
 +    if (claim != null) {
 +      c = claim[0];
 +    }
 +
 +    return c;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see JWT#getAudienceClaims()
 +   */
 +  @Override
 +  public String[] getAudienceClaims() {
 +    String[] claims = null;
 +
 +    try {
 +      claims = jwt.getJWTClaimsSet().getStringArrayClaim(JWT.AUDIENCE);
 +    } catch (ParseException e) {
 +      log.unableToParseToken(e);
 +    }
 +
 +    return claims;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see JWT#getExpires()
 +   */
 +  @Override
 +  public String getExpires() {
-     return getClaim(JWT.EXPIRES);
++    Date expires = getExpiresDate();
++    if (expires != null) {
++      return String.valueOf(expires.getTime());
++    }
++    return null;
 +  }
 +
 +  @Override
 +  public Date getExpiresDate() {
 +    Date date = null;
 +    try {
 +      date = jwt.getJWTClaimsSet().getExpirationTime();
 +    } catch (ParseException e) {
 +      log.unableToParseToken(e);
 +    }
 +    return date;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see JWT#getPrincipal()
 +   */
 +  @Override
 +  public String getPrincipal() {
 +    return getClaim(JWT.PRINCIPAL);
 +  }
 +
-   
++
 +  /* (non-Javadoc)
-    * @see JWT#getPrincipal()
++   * @see org.apache.knox.gateway.services.security.token.impl.JWT#sign(JWSSigner)
 +   */
 +  @Override
 +  public void sign(JWSSigner signer) {
 +    try {
 +      jwt.sign(signer);
 +    } catch (JOSEException e) {
 +      log.unableToSignToken(e);
 +    }
 +  }
 +
-   /**
-    * @param verifier
-    * @return
++  /* (non-Javadoc)
++   * @see org.apache.knox.gateway.services.security.token.impl.JWT#verify(JWSVerifier)
 +   */
 +  public boolean verify(JWSVerifier verifier) {
 +    boolean rc = false;
-     
++
 +    try {
 +      rc = jwt.verify(verifier);
 +    } catch (JOSEException e) {
 +      // TODO Auto-generated catch block
 +      log.unableToVerifyToken(e);
 +    }
-     
++
 +    return rc;
-   }  
++  }
 +}

http://git-wip-us.apache.org/repos/asf/knox/blob/b3107e91/gateway-spi/src/test/java/org/apache/knox/gateway/services/security/token/impl/JWTTokenTest.java
----------------------------------------------------------------------
diff --cc gateway-spi/src/test/java/org/apache/knox/gateway/services/security/token/impl/JWTTokenTest.java
index 3ce28c5,0000000..1b0df9e
mode 100644,000000..100644
--- a/gateway-spi/src/test/java/org/apache/knox/gateway/services/security/token/impl/JWTTokenTest.java
+++ b/gateway-spi/src/test/java/org/apache/knox/gateway/services/security/token/impl/JWTTokenTest.java
@@@ -1,213 -1,0 +1,223 @@@
 +/**
 + * 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.knox.gateway.services.security.token.impl;
 +
 +import java.security.KeyPair;
 +import java.security.KeyPairGenerator;
 +import java.security.NoSuchAlgorithmException;
 +import java.security.interfaces.RSAPrivateKey;
 +import java.security.interfaces.RSAPublicKey;
 +import java.util.ArrayList;
++import java.util.Date;
 +
 +import org.junit.Test;
 +
 +import com.nimbusds.jose.JWSAlgorithm;
 +import com.nimbusds.jose.JWSSigner;
 +import com.nimbusds.jose.JWSVerifier;
 +import com.nimbusds.jose.crypto.RSASSASigner;
 +import com.nimbusds.jose.crypto.RSASSAVerifier;
 +
 +public class JWTTokenTest extends org.junit.Assert {
 +  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\"}";
++  private static final String HEADER = "{\"typ\":\"JWT\",\"alg\":\"HS256\"}";
 +
 +  private RSAPublicKey publicKey;
 +  private RSAPrivateKey privateKey;
 +
 +  public JWTTokenTest() throws Exception, NoSuchAlgorithmException {
 +    KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
 +    kpg.initialize(2048);
 +
 +    KeyPair kp = kpg.genKeyPair();
 +    publicKey = (RSAPublicKey) kp.getPublic();
 +    privateKey = (RSAPrivateKey) kp.getPrivate();
 +  }
 +
++  @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");
++    assertEquals(token.getClaim("jti"), "aa7f8d0a95c");
 +  }
 +
 +  @Test
 +  public void testTokenCreation() throws Exception {
 +    String[] claims = new String[4];
 +    claims[0] = "KNOXSSO";
 +    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("KNOXSSO", token.getIssuer());
 +    assertEquals("john.doe@example.com", token.getSubject());
 +    assertEquals("https://login.example.com", token.getAudience());
 +  }
 +
 +  @Test
 +  public void testTokenCreationWithAudienceListSingle() throws Exception {
 +    String[] claims = new String[4];
 +    claims[0] = "KNOXSSO";
 +    claims[1] = "john.doe@example.com";
 +    claims[2] = null;
 +    claims[3] = Long.toString( ( System.currentTimeMillis()/1000 ) + 300);
 +    ArrayList<String> audiences = new ArrayList<String>();
 +    audiences.add("https://login.example.com");
 +
 +    JWTToken token = new JWTToken("RS256", claims, audiences);
 +
 +    assertEquals("KNOXSSO", token.getIssuer());
 +    assertEquals("john.doe@example.com", token.getSubject());
 +    assertEquals("https://login.example.com", token.getAudience());
 +    assertEquals(1, token.getAudienceClaims().length);
 +  }
 +
 +  @Test
 +  public void testTokenCreationWithAudienceListMultiple() throws Exception {
 +    String[] claims = new String[4];
 +    claims[0] = "KNOXSSO";
 +    claims[1] = "john.doe@example.com";
 +    claims[2] = null;
 +    claims[3] = Long.toString( ( System.currentTimeMillis()/1000 ) + 300);
 +    ArrayList<String> audiences = new ArrayList<String>();
 +    audiences.add("https://login.example.com");
 +    audiences.add("KNOXSSO");
 +
 +    JWTToken token = new JWTToken("RS256", claims, audiences);
 +
 +    assertEquals("KNOXSSO", token.getIssuer());
 +    assertEquals("john.doe@example.com", token.getSubject());
 +    assertEquals("https://login.example.com", token.getAudience());
 +    assertEquals(2, token.getAudienceClaims().length);
 +  }
 +
 +  @Test
 +  public void testTokenCreationWithAudienceListCombined() throws Exception {
 +    String[] claims = new String[4];
 +    claims[0] = "KNOXSSO";
 +    claims[1] = "john.doe@example.com";
 +    claims[2] = "LJM";
 +    claims[3] = Long.toString( ( System.currentTimeMillis()/1000 ) + 300);
 +    ArrayList<String> audiences = new ArrayList<String>();
 +    audiences.add("https://login.example.com");
 +    audiences.add("KNOXSSO");
 +
 +    JWTToken token = new JWTToken("RS256", claims, audiences);
 +
 +    assertEquals("KNOXSSO", token.getIssuer());
 +    assertEquals("john.doe@example.com", token.getSubject());
 +    assertEquals("https://login.example.com", token.getAudience());
 +    assertEquals(3, token.getAudienceClaims().length);
 +  }
 +
 +  @Test
 +  public void testTokenCreationWithNullAudienceList() throws Exception {
 +    String[] claims = new String[4];
 +    claims[0] = "KNOXSSO";
 +    claims[1] = "john.doe@example.com";
 +    claims[2] = null;
 +    claims[3] = Long.toString( ( System.currentTimeMillis()/1000 ) + 300);
 +    ArrayList<String> audiences = null;
 +
 +    JWTToken token = new JWTToken("RS256", claims, audiences);
 +
 +    assertEquals("KNOXSSO", token.getIssuer());
 +    assertEquals("john.doe@example.com", token.getSubject());
 +    assertEquals(null, token.getAudience());
 +    assertArrayEquals(null, token.getAudienceClaims());
 +  }
 +
 +  @Test
 +  public void testTokenCreationRS512() throws Exception {
 +    String[] claims = new String[4];
 +    claims[0] = "KNOXSSO";
 +    claims[1] = "john.doe@example.com";
 +    claims[2] = "https://login.example.com";
 +    claims[3] = Long.toString( ( System.currentTimeMillis()/1000 ) + 300);
 +    JWTToken token = new JWTToken(JWSAlgorithm.RS512.getName(), claims);
 +
 +    assertEquals("KNOXSSO", token.getIssuer());
 +    assertEquals("john.doe@example.com", token.getSubject());
 +    assertEquals("https://login.example.com", token.getAudience());
 +    assertTrue(token.getHeader().contains(JWSAlgorithm.RS512.getName()));
 +  }
 +
 +  @Test
 +  public void testTokenSignature() throws Exception {
 +    String[] claims = new String[4];
 +    claims[0] = "KNOXSSO";
 +    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("KNOXSSO", token.getIssuer());
 +    assertEquals("john.doe@example.com", token.getSubject());
 +    assertEquals("https://login.example.com", token.getAudience());
 +
 +    // Sign the token
 +    JWSSigner signer = new RSASSASigner(privateKey);
 +    token.sign(signer);
 +    assertTrue(token.getSignaturePayload().length > 0);
 +
 +    // Verify the signature
 +    JWSVerifier verifier = new RSASSAVerifier((RSAPublicKey) publicKey);
 +    assertTrue(token.verify(verifier));
 +  }
 +
 +  @Test
 +  public void testTokenSignatureRS512() throws Exception {
 +    String[] claims = new String[4];
 +    claims[0] = "KNOXSSO";
 +    claims[1] = "john.doe@example.com";
 +    claims[2] = "https://login.example.com";
 +    claims[3] = Long.toString( ( System.currentTimeMillis()/1000 ) + 300);
 +    JWTToken token = new JWTToken(JWSAlgorithm.RS512.getName(), claims);
 +
 +    assertEquals("KNOXSSO", token.getIssuer());
 +    assertEquals("john.doe@example.com", token.getSubject());
 +    assertEquals("https://login.example.com", token.getAudience());
 +    assertTrue(token.getHeader().contains(JWSAlgorithm.RS512.getName()));
 +
 +    // Sign the token
 +    JWSSigner signer = new RSASSASigner(privateKey);
 +    token.sign(signer);
 +    assertTrue(token.getSignaturePayload().length > 0);
 +
 +    // Verify the signature
 +    JWSVerifier verifier = new RSASSAVerifier((RSAPublicKey) publicKey);
 +    assertTrue(token.verify(verifier));
 +  }
 +
++  @Test
++  public void testTokenExpiry() throws Exception {
++    String[] claims = new String[4];
++    claims[0] = "KNOXSSO";
++    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);
++
++    assertNotNull(token.getExpires());
++    assertNotNull(token.getExpiresDate());
++    assertEquals(token.getExpiresDate(), new Date(Long.valueOf(token.getExpires())));
++  }
 +}

http://git-wip-us.apache.org/repos/asf/knox/blob/b3107e91/gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
----------------------------------------------------------------------
diff --cc gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
index e7512b3,0000000..8abf5aa
mode 100644,000000..100644
--- a/gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
+++ b/gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
@@@ -1,612 -1,0 +1,617 @@@
 +/**
 + * 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.knox.gateway;
 +
 +import org.apache.commons.lang.StringUtils;
 +import org.apache.hadoop.conf.Configuration;
 +import org.apache.knox.gateway.config.GatewayConfig;
 +
 +import java.io.File;
 +import java.net.InetSocketAddress;
 +import java.net.UnknownHostException;
 +import java.util.ArrayList;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.concurrent.ConcurrentHashMap;
 +
 +public class GatewayTestConfig extends Configuration implements GatewayConfig {
 +
 +  /* Websocket defaults */
 +  public static final boolean DEFAULT_WEBSOCKET_FEATURE_ENABLED = false;
 +  public static final int DEFAULT_WEBSOCKET_MAX_TEXT_MESSAGE_SIZE = Integer.MAX_VALUE;;
 +  public static final int DEFAULT_WEBSOCKET_MAX_BINARY_MESSAGE_SIZE = Integer.MAX_VALUE;;
 +  public static final int DEFAULT_WEBSOCKET_MAX_TEXT_MESSAGE_BUFFER_SIZE = 32768;
 +  public static final int DEFAULT_WEBSOCKET_MAX_BINARY_MESSAGE_BUFFER_SIZE = 32768;
 +  public static final int DEFAULT_WEBSOCKET_INPUT_BUFFER_SIZE = 4096;
 +  public static final int DEFAULT_WEBSOCKET_ASYNC_WRITE_TIMEOUT = 60000;
 +  public static final int DEFAULT_WEBSOCKET_IDLE_TIMEOUT = 300000;
 +
 +  private String gatewayHomeDir = "gateway-home";
 +  private String hadoopConfDir = "hadoop";
 +  private String gatewayHost = "localhost";
 +  private int gatewayPort = 0;
 +  private String gatewayPath = "gateway";
 +  private boolean hadoopKerberosSecured = false;
 +  private String kerberosConfig = "/etc/knox/conf/krb5.conf";
 +  private boolean kerberosDebugEnabled = false;
 +  private String kerberosLoginConfig = "/etc/knox/conf/krb5JAASLogin.conf";
 +  private String frontendUrl = null;
 +  private boolean xForwardedEnabled = true;
 +  private String gatewayApplicationsDir = null;
 +  private String gatewayServicesDir;
 +  private String defaultTopologyName = "default";
 +  private List<String> includedSSLCiphers = null;
 +  private List<String> excludedSSLCiphers = null;
 +  private boolean sslEnabled = false;
 +  private String truststoreType = "jks";
 +  private String keystoreType = "jks";
 +  private boolean isTopologyPortMappingEnabled = true;
 +  private ConcurrentHashMap<String, Integer> topologyPortMapping = new ConcurrentHashMap<>();
 +  private int backupVersionLimit = -1;
 +  private long backupAgeLimit = -1;
 +
 +  public void setGatewayHomeDir( String gatewayHomeDir ) {
 +    this.gatewayHomeDir = gatewayHomeDir;
 +  }
 +
 +  public String getGatewayHomeDir() {
 +    return this.gatewayHomeDir;
 +  }
 +
 +  @Override
 +  public String getGatewayConfDir() {
 +    return gatewayHomeDir;
 +  }
 +
 +  @Override
 +  public String getGatewayDataDir() {
 +    return gatewayHomeDir;
 +  }
 +
 +  @Override
 +  public String getGatewaySecurityDir() {
 +    return gatewayHomeDir + "/security";
 +  }
 +
 +  @Override
 +  public String getGatewayTopologyDir() {
 +    return gatewayHomeDir + "/topologies";
 +  }
 +
 +  @Override
 +  public String getGatewayDeploymentDir() {
 +    return gatewayHomeDir + "/deployments";
 +  }
 +
 +//  public void setDeploymentDir( String clusterConfDir ) {
 +//    this.deployDir = clusterConfDir;
 +//  }
 +
 +  @Override
 +  public String getHadoopConfDir() {
 +    return hadoopConfDir;
 +  }
 +
 +//  public void setHadoopConfDir( String hadoopConfDir ) {
 +//    this.hadoopConfDir = hadoopConfDir;
 +//  }
 +
 +  @Override
 +  public String getGatewayHost() {
 +    return gatewayHost;
 +  }
 +
 +//  public void setGatewayHost( String gatewayHost ) {
 +//    this.gatewayHost = gatewayHost;
 +//  }
 +
 +  @Override
 +  public int getGatewayPort() {
 +    return gatewayPort;
 +  }
 +
 +//  public void setGatewayPort( int gatewayPort ) {
 +//    this.gatewayPort = gatewayPort;
 +//  }
 +
 +  @Override
 +  public String getGatewayPath() {
 +    return gatewayPath;
 +  }
 +
 +  public void setGatewayPath( String gatewayPath ) {
 +    this.gatewayPath = gatewayPath;
 +  }
 +
 +  @Override
 +  public InetSocketAddress getGatewayAddress() throws UnknownHostException {
 +    return new InetSocketAddress( getGatewayHost(), getGatewayPort() );
 +  }
 +
 +
 +  public long getGatewayIdleTimeout() {
 +    return 0l;
 +  }
 +
 +  @Override
 +  public boolean isSSLEnabled() {
 +    return sslEnabled;
 +  }
 +
 +  public void setSSLEnabled( boolean sslEnabled ) {
 +    this.sslEnabled = sslEnabled;
 +  }
 +
 +  @Override
 +  public boolean isHadoopKerberosSecured() {
 +    return hadoopKerberosSecured;
 +  }
 +
 +  public void setHadoopKerberosSecured(boolean hadoopKerberosSecured) {
 +    this.hadoopKerberosSecured = hadoopKerberosSecured;
 +  }
 +
 +  @Override
 +  public String getKerberosConfig() {
 +    return kerberosConfig;
 +  }
 +
 +  public void setKerberosConfig(String kerberosConfig) {
 +    this.kerberosConfig = kerberosConfig;
 +  }
 +
 +  @Override
 +  public boolean isKerberosDebugEnabled() {
 +    return kerberosDebugEnabled;
 +  }
 +
 +  public void setKerberosDebugEnabled(boolean kerberosDebugEnabled) {
 +    this.kerberosDebugEnabled = kerberosDebugEnabled;
 +  }
 +
 +  @Override
 +  public String getKerberosLoginConfig() {
 +    return kerberosLoginConfig;
 +  }
 +
 +  @Override
 +  public String getDefaultTopologyName() {
 +    return defaultTopologyName;
 +  }
 +
 +  public void setDefaultTopologyName( String defaultTopologyName ) {
 +    this.defaultTopologyName = defaultTopologyName;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see GatewayConfig#getDefaultAppRedirectPath()
 +   */
 +  @Override
 +  public String getDefaultAppRedirectPath() {
 +
 +    if(StringUtils.isBlank(this.defaultTopologyName)) {
 +      return "/gateway/sandbox";
 +    } else {
 +      return "/gateway/"+this.defaultTopologyName;
 +    }
 +
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see GatewayConfig#getFrontendUrl()
 +   */
 +  @Override
 +  public String getFrontendUrl() { return frontendUrl; }
 +
 +  public void setFrontendUrl( String frontendUrl ) {
 +    this.frontendUrl = frontendUrl;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see GatewayConfig#getExcludedSSLProtocols()
 +   */
 +  @Override
 +  public List getExcludedSSLProtocols() {
 +    List<String> protocols = new ArrayList<String>();
 +    protocols.add("SSLv3");
 +    return protocols;
 +  }
 +
 +  @Override
 +  public List getIncludedSSLCiphers() {
 +    return includedSSLCiphers;
 +  }
 +
 +  public void setIncludedSSLCiphers( List<String> list ) {
 +    includedSSLCiphers = list;
 +  }
 +
 +  @Override
 +  public List getExcludedSSLCiphers() {
 +    return excludedSSLCiphers;
 +  }
 +
 +  public void setExcludedSSLCiphers( List<String> list ) {
 +    excludedSSLCiphers = list;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see GatewayConfig#isClientAuthNeeded()
 +   */
 +  @Override
 +  public boolean isClientAuthNeeded() {
 +    // TODO Auto-generated method stub
 +    return false;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see GatewayConfig#getTruststorePath()
 +   */
 +  @Override
 +  public String getTruststorePath() {
 +    // TODO Auto-generated method stub
 +    return null;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see GatewayConfig#getTrustAllCerts()
 +   */
 +  @Override
 +  public boolean getTrustAllCerts() {
 +    // TODO Auto-generated method stub
 +    return false;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see GatewayConfig#getTruststoreType()
 +   */
 +  @Override
 +  public String getTruststoreType() {
 +    return truststoreType;
 +  }
 +
 +  public void setTruststoreType( String truststoreType ) {
 +    this.truststoreType = truststoreType;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see GatewayConfig#getKeystoreType()
 +   */
 +  @Override
 +  public String getKeystoreType() {
 +    return keystoreType;
 +  }
 +
 +  public void setKeystoreType( String keystoreType ) {
 +    this.keystoreType = keystoreType;
 +  }
 +
 +  public void setKerberosLoginConfig(String kerberosLoginConfig) {
 +   this.kerberosLoginConfig = kerberosLoginConfig;
 +  }
 +
 +   @Override
 +   public String getGatewayServicesDir() {
 +    if( gatewayServicesDir != null ) {
 +      return gatewayServicesDir;
 +    } else {
 +      File targetDir = new File( System.getProperty( "user.dir" ), "target/services" );
 +      return targetDir.getPath();
 +    }
 +  }
 +
 +  public void setGatewayServicesDir( String gatewayServicesDir ) {
 +    this.gatewayServicesDir = gatewayServicesDir;
 +  }
 +
 +  @Override
 +  public String getGatewayApplicationsDir() {
 +    if( gatewayApplicationsDir != null ) {
 +      return gatewayApplicationsDir;
 +    } else {
 +      return getGatewayConfDir() + "/applications";
 +    }
 +  }
 +
 +  public void setGatewayApplicationsDir( String gatewayApplicationsDir ) {
 +    this.gatewayApplicationsDir = gatewayApplicationsDir;
 +   }
 +
 +  @Override
 +  public boolean isXForwardedEnabled() {
 +    return xForwardedEnabled;
 +  }
 +
 +  public void setXForwardedEnabled(boolean enabled) {
 +    xForwardedEnabled = enabled;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see GatewayConfig#getEphemeralDHKeySize()
 +   */
 +  @Override
 +  public String getEphemeralDHKeySize() {
 +    return "2048";
 +  }
 +
 +  @Override
 +  public int getHttpClientMaxConnections() {
 +    return 16;
 +  }
 +
 +  @Override
 +  public int getHttpClientConnectionTimeout() {
 +    return -1;
 +  }
 +
 +  @Override
 +  public int getHttpClientSocketTimeout() {
 +    return -1;
 +  }
 +
 +  @Override
 +  public int getThreadPoolMax() {
 +    return 16;
 +  }
 +
 +  @Override
 +  public int getHttpServerRequestBuffer() {
 +    return 16*1024;
 +  }
 +
 +  @Override
 +  public int getHttpServerRequestHeaderBuffer() {
 +    return 8*1024;
 +  }
 +
 +  @Override
 +  public int getHttpServerResponseBuffer() {
 +    return 32*1024;
 +  }
 +
 +  @Override
 +  public int getHttpServerResponseHeaderBuffer() {
 +    return 8*1024;
 +  }
 +
 +  public void setGatewayDeploymentsBackupVersionLimit( int newBackupVersionLimit ) {
 +    backupVersionLimit = newBackupVersionLimit;
 +  }
 +
 +  public int getGatewayDeploymentsBackupVersionLimit() {
 +    return backupVersionLimit;
 +  }
 +
 +  public void setTopologyPortMapping(ConcurrentHashMap<String, Integer> topologyPortMapping) {
 +    this.topologyPortMapping = topologyPortMapping;
 +  }
 +
 +  public void setGatewayPortMappingEnabled(
 +      boolean topologyPortMappingEnabled) {
 +    isTopologyPortMappingEnabled = topologyPortMappingEnabled;
 +  }
 +
 +  @Override
 +  public long getGatewayDeploymentsBackupAgeLimit() {
 +    return backupAgeLimit;
 +  }
 +
 +  public void setGatewayDeploymentsBackupAgeLimit( long newBackupAgeLimit ) {
 +    backupAgeLimit = newBackupAgeLimit;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see GatewayConfig#getSigningKeystoreName()
 +   */
 +  @Override
 +  public String getSigningKeystoreName() {
 +    return null;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see GatewayConfig#getSigningKeyAlias()
 +   */
 +  @Override
 +  public String getSigningKeyAlias() {
 +    return null;
 +  }
 +
 +  @Override
 +  public List<String> getGlobalRulesServices() {
 +    ArrayList<String> services = new ArrayList<>();
 +    services.add("WEBHDFS");
 +    services.add("HBASE");
 +    services.add("HIVE");
 +    services.add("OOZIE");
 +    services.add("RESOURCEMANAGER");
 +    services.add("STORM");
 +    return services;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see GatewayConfig#isWebsocketEnabled()
 +   */
 +  @Override
 +  public boolean isWebsocketEnabled() {
 +    return DEFAULT_WEBSOCKET_FEATURE_ENABLED;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see GatewayConfig#getWebsocketMaxTextMessageSize()
 +   */
 +  @Override
 +  public int getWebsocketMaxTextMessageSize() {
 +    return DEFAULT_WEBSOCKET_MAX_TEXT_MESSAGE_SIZE;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see GatewayConfig#getWebsocketMaxBinaryMessageSize()
 +   */
 +  @Override
 +  public int getWebsocketMaxBinaryMessageSize() {
 +    return DEFAULT_WEBSOCKET_MAX_BINARY_MESSAGE_SIZE;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see GatewayConfig#getWebsocketMaxTextMessageBufferSize()
 +   */
 +  @Override
 +  public int getWebsocketMaxTextMessageBufferSize() {
 +    return DEFAULT_WEBSOCKET_MAX_TEXT_MESSAGE_BUFFER_SIZE;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see GatewayConfig#getWebsocketMaxBinaryMessageBufferSize()
 +   */
 +  @Override
 +  public int getWebsocketMaxBinaryMessageBufferSize() {
 +    return DEFAULT_WEBSOCKET_MAX_BINARY_MESSAGE_BUFFER_SIZE;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see GatewayConfig#getWebsocketInputBufferSize()
 +   */
 +  @Override
 +  public int getWebsocketInputBufferSize() {
 +    return DEFAULT_WEBSOCKET_INPUT_BUFFER_SIZE;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see GatewayConfig#getWebsocketAsyncWriteTimeout()
 +   */
 +  @Override
 +  public int getWebsocketAsyncWriteTimeout() {
 +    return DEFAULT_WEBSOCKET_ASYNC_WRITE_TIMEOUT;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see GatewayConfig#getWebsocketIdleTimeout()
 +   */
 +  @Override
 +  public int getWebsocketIdleTimeout() {
 +    return DEFAULT_WEBSOCKET_IDLE_TIMEOUT;
 +  }
 +
 +  @Override
 +  public boolean isMetricsEnabled() {
 +    return false;
 +  }
 +
 +  @Override
 +  public boolean isJmxMetricsReportingEnabled() {
 +    return false;
 +  }
 +
 +  @Override
 +  public boolean isGraphiteMetricsReportingEnabled() {
 +    return false;
 +  }
 +
 +  @Override
 +  public String getGraphiteHost() {
 +    return null;
 +  }
 +
 +  @Override
 +  public int getGraphitePort() {
 +    return 0;
 +  }
 +
 +  @Override
 +  public int getGraphiteReportingFrequency() {
 +    return 0;
 +  }
 +
 +  /* (non-Javadoc)
 +   * @see GatewayConfig#getMimeTypesToCompress()
 +   */
 +  @Override
 +  public List<String> getMimeTypesToCompress() {
 +    return new ArrayList<String>();
 +  }
 +
 +  @Override
 +  public  boolean isCookieScopingToPathEnabled() {
 +    return false;
 +  }
 +
 +  @Override
 +  public String getHeaderNameForRemoteAddress() {
 +    return "X-Forwarded-For";
 +  }
 +
 +  @Override
 +  public String getAlgorithm() {
 +    return null;
 +  }
 +
 +  @Override
 +  public String getPBEAlgorithm() {
 +    return null;
 +  }
 +
 +  @Override
 +  public String getTransformation() {
 +    return null;
 +  }
 +
 +  @Override
 +  public String getSaltSize() {
 +    return null;
 +  }
 +
 +  @Override
 +  public String getIterationCount() {
 +    return null;
 +  }
 +
 +  @Override
 +  public String getKeyLength() {
 +    return null;
 +  }
 +
 +  /**
 +   * Map of Topology names and their ports.
 +   *
 +   * @return
 +   */
 +  @Override
 +  public Map<String, Integer> getGatewayPortMappings() {
 +    return topologyPortMapping;
 +  }
 +
 +  /**
 +   * Is the Port Mapping feature on ?
 +   *
 +   * @return
 +   */
 +  @Override
 +  public boolean isGatewayPortMappingEnabled() {
 +    return isTopologyPortMappingEnabled;
 +  }
 +
 +  @Override
 +  public boolean isGatewayServerHeaderEnabled() {
 +	return false;
 +  }
++
++  @Override
++  public boolean isClientAuthWanted() {
++    return false;
++  }
 +}

http://git-wip-us.apache.org/repos/asf/knox/blob/b3107e91/gateway-util-common/src/main/java/org/apache/knox/gateway/util/HttpUtils.java
----------------------------------------------------------------------
diff --cc gateway-util-common/src/main/java/org/apache/knox/gateway/util/HttpUtils.java
index e87c3fb,0000000..8dc264b
mode 100644,000000..100644
--- a/gateway-util-common/src/main/java/org/apache/knox/gateway/util/HttpUtils.java
+++ b/gateway-util-common/src/main/java/org/apache/knox/gateway/util/HttpUtils.java
@@@ -1,123 -1,0 +1,122 @@@
 +/**
 + * Licensed to the Apache Software Foundation (ASF) under one
 + * or more contributor license agreements.  See the NOTICE file
 + * distributed with this work for additional information
 + * regarding copyright ownership.  The ASF licenses this file
 + * to you under the Apache License, Version 2.0 (the
 + * "License"); you may not use this file except in compliance
 + * with the License.  You may obtain a copy of the License at
 + * <p/>
 + * http://www.apache.org/licenses/LICENSE-2.0
 + * <p/>
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +package org.apache.knox.gateway.util;
 +
 +import java.io.UnsupportedEncodingException;
 +import java.net.URL;
 +import java.net.URLDecoder;
++import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.HashMap;
- import java.util.LinkedHashMap;
- import java.util.LinkedList;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.StringTokenizer;
 +
 +public class HttpUtils {
 +
 +  public static Map<String, List<String>> splitQuery(String queryString)
 +      throws UnsupportedEncodingException {
-     final Map<String, List<String>> queryPairs = new LinkedHashMap<String, List<String>>();
++    final Map<String, List<String>> queryPairs = new HashMap<String, List<String>>();
 +    if (queryString == null || queryString.trim().isEmpty()) {
 +      return queryPairs;
 +    }
 +    final String[] pairs = queryString.split("&");
 +    for (String pair : pairs) {
 +      final int idx = pair.indexOf("=");
 +      final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), "UTF-8") : pair;
 +      if (!queryPairs.containsKey(key)) {
-         queryPairs.put(key, new LinkedList<String>());
++        queryPairs.put(key, new ArrayList<String>());
 +      }
 +      final String value = idx > 0 && pair.length() > idx + 1 
 +          ? URLDecoder.decode(pair.substring(idx + 1), "UTF-8") : "";
 +      queryPairs.get(key).add(value);
 +    }
 +    return queryPairs;
 +  }
 +
 +  public static Map<String,String[]> parseQueryString( String queryString ) {
 +    Map<String,String[]> map = new HashMap<>();
 +    if( queryString != null && !queryString.isEmpty() ) {
 +      StringTokenizer parser = new StringTokenizer( queryString, "&?;=", true );
 +      String name = null;
 +      String value = null;
 +      while( parser.hasMoreTokens() ) {
 +        String token = parser.nextToken();
 +        String ttoken = token.trim();
 +        if( ttoken.length() == 1 ) {
 +          char c = ttoken.charAt( 0 );
 +          switch( c ) {
 +            case '&':
 +            case '?':
 +            case ';':
 +              addQueryStringParam( map, name, value );
 +              name = null;
 +              value = null;
 +              continue;
 +            case '=':
 +              if( name == null ) {
 +                name = "";
 +                value = "";
 +              } else if( name.isEmpty() ) {
 +                addQueryStringParam( map, name, value );
 +                name = "";
 +                value = "";
 +              } else {
 +                value = "";
 +              }
 +              continue;
 +          }
 +        }
 +        if( name == null ) {
 +          name = token;
 +        } else {
 +          value = token;
 +        }
 +      } // while
 +      if( name != null ) {
 +        addQueryStringParam( map, name, value );
 +      }
 +    }
 +    return map;
 +  }
 +
 +  private static final String urlDecodeUtf8( String s ) {
 +    if( s != null ) {
 +      try {
 +        s = URLDecoder.decode( s, "UTF-8" );
 +      } catch( UnsupportedEncodingException e ) {
 +        // Ignore it.
 +      }
 +    }
 +    return s;
 +  }
 +
 +  static final void addQueryStringParam( final Map<String,String[]> map, String name, String value ) {
 +    name = urlDecodeUtf8( name );
 +    value = urlDecodeUtf8( value );
 +    String[] values = map.get( name );
 +    if( values == null ) {
 +      values = new String[]{ value };
 +    } else {
 +      values = Arrays.copyOf( values, values.length + 1 );
 +      values[ values.length-1 ] = value;
 +    }
 +    map.put( name, values );
 +  }
 +
 +}