You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by hs...@apache.org on 2011/05/21 12:24:36 UTC

svn commit: r1125661 - in /shindig/trunk/java/common/src: main/java/org/apache/shindig/auth/AuthenticationServletFilter.java test/java/org/apache/shindig/auth/AuthenticationServletFilterTest.java

Author: hsaputra
Date: Sat May 21 10:24:36 2011
New Revision: 1125661

URL: http://svn.apache.org/viewvc?rev=1125661&view=rev
Log:
Add injection to auth realm and sets auth header when InvalidAuthenticationException occur when sending 401 status.
Update unit test.

CR at https://reviews.apache.org/r/760/


Modified:
    shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AuthenticationServletFilter.java
    shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/AuthenticationServletFilterTest.java

Modified: shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AuthenticationServletFilter.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AuthenticationServletFilter.java?rev=1125661&r1=1125660&r2=1125661&view=diff
==============================================================================
--- shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AuthenticationServletFilter.java (original)
+++ shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AuthenticationServletFilter.java Sat May 21 10:24:36 2011
@@ -21,9 +21,11 @@ import com.google.common.base.Charsets;
 import com.google.common.base.Preconditions;
 import com.google.inject.Inject;
 
+import org.apache.shindig.common.Nullable;
 import org.apache.shindig.common.logging.i18n.MessageKeys;
 import org.apache.shindig.common.servlet.InjectedFilter;
 
+import com.google.inject.name.Named;
 import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
@@ -53,17 +55,20 @@ import javax.servlet.http.HttpServletRes
  * additional handler.
  */
 public class AuthenticationServletFilter extends InjectedFilter {
-  public static final String AUTH_TYPE_OAUTH = "OAuth";
-
-  // At some point change this to a container specific realm
-  private static final String REALM = "shindig";
- 
-  private List<AuthenticationHandler> handlers;
+  public static final String WWW_AUTHENTICATE_HEADER = "WWW-Authenticate";
 
   //class name for logging purpose
   private static final String CLASSNAME = AuthenticationServletFilter.class.getName();
   private static final Logger LOG = Logger.getLogger(CLASSNAME, MessageKeys.MESSAGES);
-  
+
+  private String realm = "shindig";
+  private List<AuthenticationHandler> handlers;
+
+  @Inject(optional = true)
+  public void setAuthenticationRealm(@Named("shindig.authentication.realm") String realm) {
+    this.realm = realm;
+  }
+
   @Inject
   public void setAuthenticationHandlers(List<AuthenticationHandler> handlers) {
     this.handlers = handlers;
@@ -71,18 +76,19 @@ public class AuthenticationServletFilter
 
   public void destroy() { }
 
-  public void doFilter(ServletRequest request, ServletResponse response,
-      FilterChain chain) throws IOException, ServletException {
-
+  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+      throws IOException, ServletException {
     if (!(request instanceof HttpServletRequest && response instanceof HttpServletResponse)) {
       throw new ServletException("Auth filter can only handle HTTP");
     }
 
     HttpServletRequest req = (HttpServletRequest) request;
     HttpServletResponse resp = (HttpServletResponse) response;
+    String authHeader = null;
 
     try {
       for (AuthenticationHandler handler : handlers) {
+        authHeader = handler.getWWWAuthenticateHeader(getRealm(req));
         SecurityToken token = handler.getSecurityTokenFromRequest(req);
         if (token != null) {
           AuthInfoUtil.setAuthTypeForRequest(req, handler.getName());
@@ -90,10 +96,8 @@ public class AuthenticationServletFilter
           callChain(chain, req, resp);
           return;
         } else {
-          String authHeader = handler.getWWWAuthenticateHeader(REALM);
-          if (authHeader != null) {
-              resp.addHeader("WWW-Authenticate", authHeader);
-          }
+          // Set auth header
+          setAuthHeader(authHeader, resp);
         }
       }
 
@@ -105,7 +109,7 @@ public class AuthenticationServletFilter
       if (LOG.isLoggable(Level.INFO)) {
         LOG.logp(Level.INFO, CLASSNAME, "doFilter", MessageKeys.ERROR_PARSING_SECURE_TOKEN, cause);
       }
-           
+
       if (iae.getAdditionalHeaders() != null) {
         for (Map.Entry<String,String> entry : iae.getAdditionalHeaders().entrySet()) {
           resp.addHeader(entry.getKey(), entry.getValue());
@@ -114,6 +118,9 @@ public class AuthenticationServletFilter
       if (iae.getRedirect() != null) {
         resp.sendRedirect(iae.getRedirect());
       } else {
+        // Set auth header
+        setAuthHeader(authHeader, resp);
+
         // For now append the cause message if set, this allows us to send any underlying oauth errors
         String message = (cause==null) ? iae.getMessage() : iae.getMessage() + cause.getMessage();
 
@@ -122,6 +129,20 @@ public class AuthenticationServletFilter
     }
   }
 
+  /**
+   * Override this to return container server specific realm.
+   * @return The authentication realm for this server.
+   */
+  protected String getRealm(HttpServletRequest request) {
+    return realm;
+  }
+
+  private void setAuthHeader(@Nullable String authHeader, HttpServletResponse response) {
+    if (authHeader != null) {
+      response.addHeader(WWW_AUTHENTICATE_HEADER, authHeader);
+    }
+  }
+
   private void callChain(FilterChain chain, HttpServletRequest request,
       HttpServletResponse response) throws IOException, ServletException {
     if (request.getAttribute(AuthenticationHandler.STASHED_BODY) != null) {
@@ -132,12 +153,10 @@ public class AuthenticationServletFilter
   }
 
   private static class StashedBodyRequestwrapper extends HttpServletRequestWrapper {
-
     final InputStream rawStream;
     ServletInputStream stream;
     BufferedReader reader;
 
-
     StashedBodyRequestwrapper(HttpServletRequest wrapped) {
       super(wrapped);
       rawStream = new ByteArrayInputStream(
@@ -146,7 +165,8 @@ public class AuthenticationServletFilter
 
     @Override
     public ServletInputStream getInputStream() throws IOException {
-      Preconditions.checkState(reader == null, "The methods getInputStream() and getReader() are mutually exclusive.");
+      Preconditions.checkState(reader == null,
+          "The methods getInputStream() and getReader() are mutually exclusive.");
 
       if (stream == null) {
         stream = new ServletInputStream() {
@@ -160,7 +180,8 @@ public class AuthenticationServletFilter
 
     @Override
     public BufferedReader getReader() throws IOException {
-      Preconditions.checkState(stream == null, "The methods getInputStream() and getReader() are mutually exclusive.");
+      Preconditions.checkState(stream == null,
+          "The methods getInputStream() and getReader() are mutually exclusive.");
 
       if (reader == null) {
         Charset charset = Charset.forName(getCharacterEncoding());

Modified: shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/AuthenticationServletFilterTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/AuthenticationServletFilterTest.java?rev=1125661&r1=1125660&r2=1125661&view=diff
==============================================================================
--- shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/AuthenticationServletFilterTest.java (original)
+++ shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/AuthenticationServletFilterTest.java Sat May 21 10:24:36 2011
@@ -17,19 +17,38 @@
  */
 package org.apache.shindig.auth;
 
+import org.apache.shindig.common.EasyMockTestCase;
+import org.apache.shindig.common.servlet.HttpServletResponseRecorder;
+
 import com.google.common.collect.ImmutableList;
+import javax.servlet.FilterChain;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import static org.easymock.EasyMock.expect;
 import org.junit.Before;
 import org.junit.Test;
 
 import javax.servlet.ServletException;
 
-public class AuthenticationServletFilterTest {
-  AuthenticationServletFilter filter;
+public class AuthenticationServletFilterTest extends EasyMockTestCase {
+  private static final String TEST_AUTH_HEADER = "Test Authentication Header";
+
+  private AuthenticationServletFilter filter;
+
+  private HttpServletRequest request;
+  private HttpServletResponse response;
+  private HttpServletResponseRecorder recorder;
+  private FilterChain chain;
+  private AuthenticationHandler nullStHandler;
 
   @Before
   public void setup() {
+    request = mock(HttpServletRequest.class);
+    response  = mock(HttpServletResponse.class);
+    recorder = new HttpServletResponseRecorder(response);
+    chain = mock(FilterChain.class);
     filter = new AuthenticationServletFilter();
-    filter.setAuthenticationHandlers(ImmutableList.<AuthenticationHandler>of());
+    nullStHandler = new NullSecurityTokenAuthenticationHandler();
   }
 
   @Test(expected = ServletException.class)
@@ -37,5 +56,29 @@ public class AuthenticationServletFilter
     filter.doFilter(null, null, null);
   }
 
+  @Test
+  public void testNullSecurityToken() throws Exception {
+    filter.setAuthenticationHandlers(ImmutableList.<AuthenticationHandler>of(nullStHandler));
+    filter.doFilter(request, recorder, chain);
+    assertEquals(TEST_AUTH_HEADER,
+        recorder.getHeader(AuthenticationServletFilter.WWW_AUTHENTICATE_HEADER));
+  }
 
+  private static class NullSecurityTokenAuthenticationHandler implements AuthenticationHandler {
+    @Override
+    public String getName() {
+      return "TestAuth";
+    }
+
+    @Override
+    public SecurityToken getSecurityTokenFromRequest(HttpServletRequest request)
+        throws InvalidAuthenticationException {
+      return null;
+    }
+
+    @Override
+    public String getWWWAuthenticateHeader(String realm) {
+      return TEST_AUTH_HEADER;
+    }
+  }
 }