|
19 | 19 | package net.sourceforge.subsonic.security;
|
20 | 20 |
|
21 | 21 | import java.io.IOException;
|
| 22 | +import java.io.UnsupportedEncodingException; |
| 23 | +import java.util.StringTokenizer; |
22 | 24 |
|
23 | 25 | import javax.servlet.Filter;
|
24 | 26 | import javax.servlet.FilterChain;
|
|
34 | 36 | import org.acegisecurity.context.SecurityContextHolder;
|
35 | 37 | import org.acegisecurity.providers.ProviderManager;
|
36 | 38 | import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
| 39 | +import org.apache.commons.codec.binary.Base64; |
37 | 40 | import org.apache.commons.codec.digest.DigestUtils;
|
38 | 41 | import org.apache.commons.lang.StringUtils;
|
39 | 42 |
|
|
51 | 54 | * Performs authentication based on credentials being present in the HTTP request parameters. Also checks
|
52 | 55 | * API versions and license information.
|
53 | 56 | * <p/>
|
54 |
| - * The username should be set in parameter "u", and the password should be set in parameter "p". |
55 | 57 | * The REST protocol version should be set in parameter "v".
|
56 | 58 | * <p/>
|
57 | 59 | * The password can either be in plain text or be UTF-8 hexencoded preceded by "enc:".
|
@@ -88,6 +90,12 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha
|
88 | 90 |
|
89 | 91 | RESTController.ErrorCode errorCode = null;
|
90 | 92 |
|
| 93 | + // Internal basic auth |
| 94 | + Credentials basicCreds = credentialsWithBasicAuthentication(httpRequest); |
| 95 | + if(basicCreds != null) { |
| 96 | + username = basicCreds.getUsername(); |
| 97 | + password = basicCreds.getPassword(); |
| 98 | + } |
91 | 99 | // The username and credentials parameters are not required if the user
|
92 | 100 | // was previously authenticated, for example using Basic Auth.
|
93 | 101 | boolean passwordOrTokenPresent = password != null || (salt != null && token != null);
|
@@ -220,4 +228,52 @@ public void setSecurityService(SecurityService securityService) {
|
220 | 228 | public void setLoginFailureLogger(LoginFailureLogger loginFailureLogger) {
|
221 | 229 | this.loginFailureLogger = loginFailureLogger;
|
222 | 230 | }
|
| 231 | + |
| 232 | + private Credentials credentialsWithBasicAuthentication(HttpServletRequest req) { |
| 233 | + String authHeader = req.getHeader("Authorization"); |
| 234 | + if (authHeader != null) { |
| 235 | + StringTokenizer st = new StringTokenizer(authHeader); |
| 236 | + if (st.hasMoreTokens()) { |
| 237 | + String basic = st.nextToken(); |
| 238 | + |
| 239 | + if (basic.equalsIgnoreCase("Basic")) { |
| 240 | + try { |
| 241 | + String credentials = new String(Base64.decodeBase64(st.nextToken().getBytes()), "UTF-8"); |
| 242 | + LOG.debug("Credentials: " + credentials); |
| 243 | + int p = credentials.indexOf(":"); |
| 244 | + if (p != -1) { |
| 245 | + String login = credentials.substring(0, p).trim(); |
| 246 | + String password = credentials.substring(p + 1).trim(); |
| 247 | + |
| 248 | + return new Credentials(login, password); |
| 249 | + } else { |
| 250 | + LOG.error("Invalid authentication token"); |
| 251 | + } |
| 252 | + } catch (UnsupportedEncodingException e) { |
| 253 | + LOG.warn("Couldn't retrieve authentication", e); |
| 254 | + } |
| 255 | + } |
| 256 | + } |
| 257 | + } |
| 258 | + |
| 259 | + return null; |
| 260 | + } |
| 261 | + |
| 262 | + private static class Credentials { |
| 263 | + private String username; |
| 264 | + private String password; |
| 265 | + |
| 266 | + Credentials(String username, String password) { |
| 267 | + this.username = username; |
| 268 | + this.password = password; |
| 269 | + } |
| 270 | + |
| 271 | + public String getPassword() { |
| 272 | + return password; |
| 273 | + } |
| 274 | + |
| 275 | + public String getUsername() { |
| 276 | + return username; |
| 277 | + } |
| 278 | + } |
223 | 279 | }
|
0 commit comments