diff --git a/scm-core/src/main/java/sonia/scm/web/filter/BasicAuthenticationFilter.java b/scm-core/src/main/java/sonia/scm/web/filter/BasicAuthenticationFilter.java
index 38532ff3ac..ba3bcbe12d 100644
--- a/scm-core/src/main/java/sonia/scm/web/filter/BasicAuthenticationFilter.java
+++ b/scm-core/src/main/java/sonia/scm/web/filter/BasicAuthenticationFilter.java
@@ -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 issue 627
+ * @see Stackoverflow Basic Authentication
+ *
+ * @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 */