use provided request encoding to decode base64 basic authentication header and fallback to ISO-8859-1, if no encoding was provided

This commit is contained in:
Sebastian Sdorra
2014-09-24 20:17:59 +02:00
parent ae65fb68ae
commit e7db65bbab

View File

@@ -35,6 +35,7 @@ package sonia.scm.web.filter;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.base.Objects;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
@@ -59,6 +60,7 @@ import sonia.scm.web.security.WebSecurityContext;
import com.sun.jersey.core.util.Base64;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Set;
@@ -87,6 +89,9 @@ public class BasicAuthenticationFilter extends AutoLoginFilter
/** marker for failed authentication */
private static final String ATTRIBUTE_FAILED_AUTH = "sonia.scm.auth.failed";
/** default encoding to decode basic authentication header */
private static final String DEFAULT_ENCODING = "ISO-8859-1";
/** the logger for BasicAuthenticationFilter */
private static final Logger logger =
LoggerFactory.getLogger(BasicAuthenticationFilter.class);
@@ -271,13 +276,14 @@ public class BasicAuthenticationFilter extends AutoLoginFilter
* @param authentication
*
* @return
*
* @throws IOException
*/
private User authenticate(HttpServletRequest request,
HttpServletResponse response, Subject subject, String authentication)
throws IOException
{
String token = authentication.substring(6);
token = new String(Base64.decode(token.getBytes()));
String token = decodeAuthenticationHeader(request, authentication);
int index = token.indexOf(CREDENTIAL_SEPARATOR);
User user = null;
@@ -331,6 +337,47 @@ public class BasicAuthenticationFilter extends AutoLoginFilter
return user;
}
/**
* Decode base64 of the basic authentication header. The method tries to use
* the charset provided by the request, if the request does not send an
* contain an encoding the method will be fallback to ISO-8859-1.
*
*
* @param request http request
* @param authentication base64 encoded basic authentication string
*
* @return decoded basic authentication header
*
* @see <a href="http://goo.gl/tZEBS3">issue 627</a>
* @see <a href="http://goo.gl/NhbZ2F">Stackoverflow Basic Authentication</a>
*
* @throws UnsupportedEncodingException
*/
private String decodeAuthenticationHeader(HttpServletRequest request,
String authentication)
throws UnsupportedEncodingException
{
String encoding = Objects.firstNonNull(request.getCharacterEncoding(),
DEFAULT_ENCODING);
String token = authentication.substring(6);
try
{
token = new String(Base64.decode(token.getBytes(encoding)));
}
catch (UnsupportedEncodingException ex)
{
logger.warn(
"encoding {} is not supported, use {} for decoding basic auth",
encoding, DEFAULT_ENCODING);
token = new String(Base64.decode(token.getBytes(DEFAULT_ENCODING)));
}
return token;
}
//~--- fields ---------------------------------------------------------------
/** scm main configuration */