Repository: knox
Updated Branches:
  refs/heads/master 06df07ec9 -> 8ba9d9235


KNOX-1314 - SSOCookieProvider should be able to derive a default provider URL

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

Branch: refs/heads/master
Commit: 8ba9d923501e8a5f016133030dd328cf2d33855a
Parents: 06df07e
Author: Larry McCay <lmc...@hw14155.home>
Authored: Thu May 17 12:52:20 2018 -0400
Committer: Larry McCay <lmc...@hw14155.home>
Committed: Thu May 17 12:52:58 2018 -0400

----------------------------------------------------------------------
 .../provider/federation/jwt/JWTMessages.java    |  2 +-
 .../jwt/filter/SSOCookieFederationFilter.java   | 35 +++++++++++++-
 .../federation/SSOCookieProviderTest.java       | 50 ++++++++++++++++++--
 3 files changed, 79 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/knox/blob/8ba9d923/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/JWTMessages.java
----------------------------------------------------------------------
diff --git 
a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/JWTMessages.java
 
b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/JWTMessages.java
index 70efa8c..5f43395 100644
--- 
a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/JWTMessages.java
+++ 
b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/JWTMessages.java
@@ -49,7 +49,7 @@ public interface JWTMessages {
   @Message( level = MessageLevel.DEBUG, text = "Sending redirect to: {0}" )
   void sendRedirectToLoginURL(String loginURL);
 
-  @Message( level = MessageLevel.ERROR, text = "Required configuration element 
for authentication provider is missing." )
+  @Message( level = MessageLevel.WARN, text = "Configuration for 
authentication provider URL is missing - will derive default URL." )
   void missingAuthenticationProviderUrlConfiguration();
 
   @Message( level = MessageLevel.DEBUG, text = "{0} Cookie has been found and 
is being processed." )

http://git-wip-us.apache.org/repos/asf/knox/blob/8ba9d923/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java
----------------------------------------------------------------------
diff --git 
a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java
 
b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java
index 1a43e3a..8537ee0 100644
--- 
a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java
+++ 
b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/SSOCookieFederationFilter.java
@@ -42,6 +42,9 @@ public class SSOCookieFederationFilter extends 
AbstractJWTFilter {
   public static final String SSO_EXPECTED_AUDIENCES = "sso.expected.audiences";
   public static final String SSO_AUTHENTICATION_PROVIDER_URL = 
"sso.authentication.provider.url";
   public static final String SSO_VERIFICATION_PEM = 
"sso.token.verification.pem";
+  public static final String X_FORWARDED_HOST = "X-Forwarded-Host";
+  public static final String X_FORWARDED_PORT = "X-Forwarded-Port";
+  public static final String X_FORWARDED_PROTO = "X-Forwarded-Proto";
 
   private static final String ORIGINAL_URL_QUERY_PARAM = "originalUrl=";
   private static final String DEFAULT_SSO_COOKIE_NAME = "hadoop-jwt";
@@ -72,7 +75,6 @@ public class SSOCookieFederationFilter extends 
AbstractJWTFilter {
     authenticationProviderUrl = 
filterConfig.getInitParameter(SSO_AUTHENTICATION_PROVIDER_URL);
     if (authenticationProviderUrl == null) {
       log.missingAuthenticationProviderUrlConfiguration();
-      throw new ServletException("Required authentication provider URL is 
missing.");
     }
 
     // token verification pem
@@ -169,6 +171,9 @@ public class SSOCookieFederationFilter extends 
AbstractJWTFilter {
    */
   protected String constructLoginURL(HttpServletRequest request) {
     String delimiter = "?";
+    if (authenticationProviderUrl == null) {
+       authenticationProviderUrl = 
deriveDefaultAuthenticationProviderUrl(request);
+    }
     if (authenticationProviderUrl.contains("?")) {
       delimiter = "&";
     }
@@ -178,9 +183,35 @@ public class SSOCookieFederationFilter extends 
AbstractJWTFilter {
     return loginURL;
   }
 
+  /**
+   * Derive a provider URL from the request assuming that the
+   * KnoxSSO endpoint is local to the endpoint serving this request.
+   * @param request
+   * @return
+   */
+  public String deriveDefaultAuthenticationProviderUrl(HttpServletRequest 
request) {
+    String scheme = null;
+    String host = null;
+    int port = 0;
+    if (!beingProxied(request)) {
+      scheme = request.getScheme();
+      host = request.getServerName();
+      port = request.getServerPort();
+    }
+    else {
+      scheme = request.getHeader(X_FORWARDED_PROTO);
+      host = request.getHeader(X_FORWARDED_HOST);
+      port = Integer.parseInt(request.getHeader(X_FORWARDED_PORT));
+    }
+    return scheme + "://" + host + ":" + port + "/" + 
"gateway/knoxsso/api/v1/websso";
+  }
+
+  private boolean beingProxied(HttpServletRequest request) {
+    return (request.getHeader(X_FORWARDED_HOST) != null);
+  }
+
   private String getOriginalQueryString(HttpServletRequest request) {
     String originalQueryString = request.getQueryString();
     return (originalQueryString == null) ? "" : "?" + originalQueryString;
   }
-
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/8ba9d923/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/SSOCookieProviderTest.java
----------------------------------------------------------------------
diff --git 
a/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/SSOCookieProviderTest.java
 
b/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/SSOCookieProviderTest.java
index 50a44ce..3aa4cb4 100644
--- 
a/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/SSOCookieProviderTest.java
+++ 
b/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/SSOCookieProviderTest.java
@@ -102,12 +102,10 @@ public class SSOCookieProviderTest extends 
AbstractJWTFilterTest {
       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 authentication 
provider URL
-      se.getMessage().contains("authentication provider URL is missing");
+      // no longer expected - let's ensure it mentions the missing 
authentication provider URL
+      fail("Servlet exception should have been thrown.");
+      se.printStackTrace();
     }
   }
 
@@ -143,6 +141,48 @@ public class SSOCookieProviderTest extends 
AbstractJWTFilterTest {
     Assert.assertEquals("https://localhost:8443/authserver?originalUrl="; + 
SERVICE_URL, loginURL);
   }
 
+  @Test
+  public void testDefaultAuthenticationProviderURL() throws Exception {
+    Properties props = new Properties();
+    handler.init(new TestFilterConfig(props));
+
+    HttpServletRequest request = 
EasyMock.createNiceMock(HttpServletRequest.class);
+    EasyMock.expect(request.getRequestURL()).andReturn(new 
StringBuffer(SERVICE_URL)).anyTimes();
+    EasyMock.expect(request.getQueryString()).andReturn(null);
+    EasyMock.expect(request.getScheme()).andReturn("https").anyTimes();
+    EasyMock.expect(request.getServerName()).andReturn("localhost").anyTimes();
+    EasyMock.expect(request.getServerPort()).andReturn(8443).anyTimes();
+    EasyMock.replay(request);
+
+    String providerURL = ((TestSSOCookieFederationProvider) 
handler).deriveDefaultAuthenticationProviderUrl(request);
+    Assert.assertNotNull("LoginURL should not be null.", providerURL);
+    Assert.assertEquals(providerURL, 
"https://localhost:8443/gateway/knoxsso/api/v1/websso";);
+
+    String loginURL = ((TestSSOCookieFederationProvider) 
handler).testConstructLoginURL(request);
+    Assert.assertNotNull("LoginURL should not be null.", loginURL);
+    Assert.assertEquals(loginURL, 
"https://localhost:8443/gateway/knoxsso/api/v1/websso?originalUrl="; + 
SERVICE_URL);
+  }
+
+  @Test
+  public void testProxiedDefaultAuthenticationProviderURL() throws Exception {
+    Properties props = new Properties();
+    handler.init(new TestFilterConfig(props));
+
+    HttpServletRequest request = 
EasyMock.createNiceMock(HttpServletRequest.class);
+    EasyMock.expect(request.getRequestURL()).andReturn(new 
StringBuffer(SERVICE_URL)).anyTimes();
+    
EasyMock.expect(request.getHeader(SSOCookieFederationFilter.X_FORWARDED_PROTO)).andReturn("https").anyTimes();
+    
EasyMock.expect(request.getHeader(SSOCookieFederationFilter.X_FORWARDED_HOST)).andReturn("remotehost").anyTimes();
+    
EasyMock.expect(request.getHeader(SSOCookieFederationFilter.X_FORWARDED_PORT)).andReturn("8443").anyTimes();
+    EasyMock.replay(request);
+
+    String providerURL = ((TestSSOCookieFederationProvider) 
handler).deriveDefaultAuthenticationProviderUrl(request);
+    Assert.assertNotNull("LoginURL should not be null.", providerURL);
+    Assert.assertEquals(providerURL, 
"https://remotehost:8443/gateway/knoxsso/api/v1/websso";);
+
+    String loginURL = ((TestSSOCookieFederationProvider) 
handler).testConstructLoginURL(request);
+    Assert.assertNotNull("LoginURL should not be null.", loginURL);
+    Assert.assertEquals(loginURL, 
"https://remotehost:8443/gateway/knoxsso/api/v1/websso?originalUrl="; + 
SERVICE_URL);
+  }
 
   @Override
   protected String getVerificationPemProperty() {

Reply via email to