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 */