|
60 | 60 |
|
61 | 61 | public class AzureBlobStorage extends CommonFileStorage {
|
62 | 62 |
|
| 63 | + // Supported authentication mechanisms are "default" and "account_key" and "sas_token" |
| 64 | + // The "default" mechanism will try environment, CLI, managed identity and workload identity |
| 65 | + |
63 | 66 | public static final String STORAGE_ACCOUNT_PROPERTY = "storageAccount";
|
64 | 67 | public static final String CONTAINER_PROPERTY = "container";
|
65 | 68 | public static final String PREFIX_PROPERTY = "prefix";
|
66 | 69 |
|
67 | 70 | public static final String CREDENTIALS_PROPERTY = "credentials";
|
68 | 71 | public static final String CREDENTIALS_DEFAULT = "default";
|
69 |
| - public static final String CREDENTIALS_ACCESS_KEY = "accessKey"; |
70 |
| - public static final String ACCESS_KEY_PROPERTY = "accessKey"; |
| 72 | + public static final String CREDENTIALS_ACCOUNT_KEY = "account_key"; |
| 73 | + public static final String CREDENTIALS_ACCESS_KEY = "access_key"; // synonym for backwards compatability |
| 74 | + public static final String CREDENTIALS_SAS_TOKEN = "sas_token"; |
| 75 | + |
| 76 | + public static final String ACCOUNT_KEY_PROPERTY = "accountKey"; |
| 77 | + public static final String ACCESS_KEY_PROPERTY = "accessKey"; // synonym for backwards compatability |
| 78 | + public static final String SAS_TOKEN_PROPERTY = "sasToken"; |
71 | 79 |
|
72 | 80 | public static final String BLOB_ENDPOINT_TEMPLATE = "https://%s.blob.core.windows.net/";
|
73 | 81 | public static final Duration STARTUP_TIMEOUT = Duration.of(1, ChronoUnit.MINUTES);
|
@@ -118,16 +126,50 @@ private CredentialsProvider prepareCredentials(Properties properties) {
|
118 | 126 | return builder -> builder.credential(credentials);
|
119 | 127 | }
|
120 | 128 |
|
121 |
| - if (CREDENTIALS_ACCESS_KEY.equalsIgnoreCase(mechanism)) { |
| 129 | + if (CREDENTIALS_ACCOUNT_KEY.equalsIgnoreCase(mechanism) || CREDENTIALS_ACCESS_KEY.equalsIgnoreCase(mechanism)) { |
| 130 | + |
| 131 | + if (CREDENTIALS_ACCESS_KEY.equalsIgnoreCase(mechanism)) { |
| 132 | + log.warn("Credentials mechanism [{}] is non-standard ans has been deprecated, please use [{}] instead", |
| 133 | + CREDENTIALS_ACCESS_KEY, CREDENTIALS_ACCOUNT_KEY); |
| 134 | + } |
122 | 135 |
|
123 |
| - log.info("Using [{}] credentials mechanism", CREDENTIALS_ACCESS_KEY); |
| 136 | + log.info("Using [{}] credentials mechanism", CREDENTIALS_ACCOUNT_KEY); |
124 | 137 |
|
125 |
| - var accessKey = properties.getProperty(ACCESS_KEY_PROPERTY); |
126 |
| - var credentials = new StorageSharedKeyCredential(storageAccount, accessKey); |
| 138 | + var accountKey = CREDENTIALS_ACCOUNT_KEY.equalsIgnoreCase(mechanism) |
| 139 | + ? properties.getProperty(ACCOUNT_KEY_PROPERTY) |
| 140 | + : properties.getProperty(ACCESS_KEY_PROPERTY); |
| 141 | + |
| 142 | + if (accountKey == null || accountKey.isEmpty()) { |
| 143 | + var message = String.format("Missing required config property [%s] for Azure blob storage", ACCOUNT_KEY_PROPERTY); |
| 144 | + log.error(message); |
| 145 | + throw new EStartup(message); |
| 146 | + } |
| 147 | + |
| 148 | + var credentials = new StorageSharedKeyCredential(storageAccount, accountKey); |
127 | 149 |
|
128 | 150 | return builder -> builder.credential(credentials);
|
129 | 151 | }
|
130 | 152 |
|
| 153 | + if (CREDENTIALS_SAS_TOKEN.equalsIgnoreCase(mechanism)) { |
| 154 | + |
| 155 | + log.info("Using [{}] credentials mechanism", CREDENTIALS_SAS_TOKEN); |
| 156 | + |
| 157 | + var rawSasToken = properties.getProperty(SAS_TOKEN_PROPERTY); |
| 158 | + |
| 159 | + if (rawSasToken == null || rawSasToken.isEmpty()) { |
| 160 | + var message = String.format("Missing required config property [%s] for Azure blob storage", SAS_TOKEN_PROPERTY); |
| 161 | + log.error(message); |
| 162 | + throw new EStartup(message); |
| 163 | + } |
| 164 | + |
| 165 | + // SAS token should be a URL query param string, including the initial "?" |
| 166 | + var sasToken = rawSasToken.startsWith("?") |
| 167 | + ? rawSasToken |
| 168 | + : "?" + rawSasToken; |
| 169 | + |
| 170 | + return builder -> builder.sasToken(sasToken); |
| 171 | + } |
| 172 | + |
131 | 173 | var message = String.format("Unrecognised credentials mechanism: [%s]", mechanism);
|
132 | 174 | log.error(message);
|
133 | 175 | throw new EStartup(message);
|
|
0 commit comments