View Javadoc
1   package cn.home1.oss.lib.common;
2   
3   import static cn.home1.oss.lib.common.crypto.CryptoConstants.COLON;
4   import static com.google.common.base.Charsets.UTF_8;
5   
6   import lombok.SneakyThrows;
7   
8   import org.apache.http.auth.AuthScope;
9   import org.apache.http.auth.Credentials;
10  import org.apache.http.auth.UsernamePasswordCredentials;
11  import org.apache.http.client.CredentialsProvider;
12  import org.apache.http.impl.client.BasicCredentialsProvider;
13  import org.springframework.util.ClassUtils;
14  
15  public abstract class BasicAuthUtils {
16  
17    public static final String BASIC_AUTH_HEADE_NAME = "Authorization";
18  
19    private static final String BAD_CREDENTIALS = "org.springframework.security.authentication.BadCredentialsException";
20    private static final Boolean BAD_CREDENTIALS_PRESENT;
21  
22    private static final String MESSAGE_FAILED_TO_DECODE_TOKEN = "Failed to decode basic authentication token";
23    private static final String MESSAGE_INVALID_TOKEN = "Invalid basic authentication token";
24  
25    static {
26      BAD_CREDENTIALS_PRESENT = ClassUtils.isPresent(BAD_CREDENTIALS, BasicAuthUtils.class.getClassLoader());
27    }
28  
29    private BasicAuthUtils() {
30    }
31  
32    public static String basicAuthHeader(final String username, final String password) {
33      final String authStr = username + COLON + password;
34      return "Basic " + CodecUtils.encodeBase64(authStr.getBytes(UTF_8));
35    }
36  
37    /**
38     * Decodes the header into a username and password.
39     * throws BadCredentialsException or IllegalArgumentException if
40     * the Basic header is not present or is not valid Base64.
41     *
42     * @param header             header
43     * @param credentialsCharset charset
44     * @return [username, password]
45     */
46    @SneakyThrows
47    public static String[] extractAndDecodeAuthHeader( //
48      final String header, //
49      final String credentialsCharset //
50    ) {
51      final String base64Token = header.substring(6);
52      byte[] decoded;
53      try {
54        decoded = CodecUtils.decodeBase64(base64Token);
55      } catch (final IllegalArgumentException cause) {
56        throw BAD_CREDENTIALS_PRESENT ? //
57          (RuntimeException) Class.forName(BAD_CREDENTIALS).getConstructor(String.class, Throwable.class) //
58            .newInstance(MESSAGE_FAILED_TO_DECODE_TOKEN, cause) : //
59          new IllegalArgumentException(MESSAGE_FAILED_TO_DECODE_TOKEN, cause);
60      }
61  
62      final String token = new String(decoded, credentialsCharset);
63      final int delim = token.indexOf(':');
64      if (delim == -1) {
65        if (!BAD_CREDENTIALS_PRESENT) {
66          throw new IllegalArgumentException(MESSAGE_INVALID_TOKEN);
67        } else {
68          throw (RuntimeException) Class.forName(BAD_CREDENTIALS) //
69            .getConstructor(String.class) //
70            .newInstance(MESSAGE_INVALID_TOKEN);
71        }
72      }
73      return new String[]{token.substring(0, delim), token.substring(delim + 1)};
74    }
75  
76    /**
77     * @deprecated remove this later.
78     * @param username username
79     * @param password password
80     * @return credentialsProvider
81     */
82    @Deprecated
83    public static CredentialsProvider basicCredentialsProvider(final String username, final String password) {
84      final Credentials credentials = new UsernamePasswordCredentials(username, password);
85      final CredentialsProvider provider = new BasicCredentialsProvider();
86      provider.setCredentials(AuthScope.ANY, credentials);
87      return provider;
88    }
89  }