Skip to content

Commit

Permalink
Authenticate requests to secondary with oauth (#11107)
Browse files Browse the repository at this point in the history
* Fixed a bug with token auth to secondaries

* Added tests

* Added recording

* Moved recording file to right place

* Fixed credentials for playback
  • Loading branch information
rickle-msft authored May 15, 2020
1 parent 66775f8 commit f35a9b1
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 4 deletions.
2 changes: 1 addition & 1 deletion sdk/storage/azure-storage-blob/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Release History

## 12.7.0-beta.1 (Unreleased)

- Fixed a bug that caused auth failures when constructing a client to a secondary endpoint using token auth.

## 12.6.1 (2020-05-06)
- Updated `azure-core` version to `1.5.0` to pickup fixes for percent encoding `UTF-8` and invalid leading bytes in a body string.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public static HttpPipeline buildPipeline(StorageSharedKeyCredential storageShare
} else if (tokenCredential != null) {
httpsValidation(tokenCredential, "bearer token", endpoint, logger);
credentialPolicy = new BearerTokenAuthenticationPolicy(tokenCredential,
String.format("%s/.default", endpoint));
String.format("%s/.default", getPrimaryEndpointForTokenAuth(endpoint)));
} else if (sasTokenCredential != null) {
credentialPolicy = new SasTokenCredentialPolicy(sasTokenCredential);
} else {
Expand All @@ -108,6 +108,19 @@ public static HttpPipeline buildPipeline(StorageSharedKeyCredential storageShare
.build();
}

/**
*
* @param endpoint The endpoint passed by the customer.
* @return The primary endpoint for the account. It may be the same endpoint passed if it is already a primary or it
* may have had "-secondary" stripped from the end of the account name.
*/
private static String getPrimaryEndpointForTokenAuth(String endpoint) {
String[] parts = endpoint.split("\\.");
parts[0] = parts[0].endsWith("-secondary") ? parts[0].substring(0, parts[0].length() - "-secondary".length())
: parts[0];
return String.join(".", parts);
}

/**
* Gets the default http log option for Storage Blob.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,15 +260,19 @@ class APISpec extends Specification {
.endpoint(String.format(defaultEndpointTemplate, primaryCredential.getAccountName()))
.httpClient(getHttpClient())

return setOauthCredentials(builder).buildClient()
}

def setOauthCredentials(BlobServiceClientBuilder builder) {
if (testMode != TestMode.PLAYBACK) {
if (testMode == TestMode.RECORD) {
builder.addPolicy(interceptorManager.getRecordPolicy())
}
// AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET
return builder.credential(new EnvironmentCredentialBuilder().build()).buildClient()
return builder.credential(new EnvironmentCredentialBuilder().build())
} else {
// Running in playback, we don't have access to the AAD environment variables, just use SharedKeyCredential.
return builder.credential(primaryCredential).buildClient()
return builder.credential(primaryCredential)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.azure.core.http.RequestConditions
import com.azure.core.util.CoreUtils
import com.azure.core.util.polling.LongRunningOperationStatus
import com.azure.identity.DefaultAzureCredentialBuilder
import com.azure.identity.EnvironmentCredentialBuilder
import com.azure.storage.blob.models.AccessTier
import com.azure.storage.blob.models.ArchiveStatus
import com.azure.storage.blob.models.BlobErrorCode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package com.azure.storage.blob

import com.azure.identity.DefaultAzureCredentialBuilder
import com.azure.identity.EnvironmentCredentialBuilder
import com.azure.storage.blob.models.BlobAnalyticsLogging
import com.azure.storage.blob.models.BlobContainerItem
import com.azure.storage.blob.models.BlobContainerListDetails
Expand Down Expand Up @@ -518,4 +519,17 @@ class ServiceAPITest extends APISpec {
then:
thrown(IllegalArgumentException)
}

def "OAuth on secondary"() {
setup:
def secondaryEndpoint = String.format(defaultEndpointTemplate,
primaryCredential.getAccountName() + "-secondary")
def serviceClient = setOauthCredentials(getServiceClientBuilder(null, secondaryEndpoint)).buildClient()

when:
serviceClient.getProperties()

then:
notThrown(Exception)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
{
"networkCallRecords" : [ {
"Method" : "PUT",
"Uri" : "https://REDACTED.blob.core.windows.net/jtcoauthonsecondary0serviceapitestoauthonsecondaryc61119591f?restype=container",
"Headers" : {
"x-ms-version" : "2019-07-07",
"User-Agent" : "azsdk-java-azure-storage-blob/12.7.0-beta.1 (11.0.6; Windows 10 10.0)",
"x-ms-client-request-id" : "d7fefafc-55bf-43c4-a2dd-4da03222e89e"
},
"Response" : {
"x-ms-version" : "2019-07-07",
"Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
"ETag" : "0x8D7F6C8A508947E",
"Last-Modified" : "Tue, 12 May 2020 23:03:11 GMT",
"retry-after" : "0",
"Content-Length" : "0",
"StatusCode" : "201",
"x-ms-request-id" : "92b1dcdb-401e-0134-45b1-28bd29000000",
"Date" : "Tue, 12 May 2020 23:03:11 GMT",
"x-ms-client-request-id" : "d7fefafc-55bf-43c4-a2dd-4da03222e89e"
},
"Exception" : null
}, {
"Method" : "PUT",
"Uri" : "https://REDACTED.blob.core.windows.net?restype=service&comp=properties",
"Headers" : {
"x-ms-version" : "2019-07-07",
"User-Agent" : "azsdk-java-azure-storage-blob/12.7.0-beta.1 (11.0.6; Windows 10 10.0)",
"x-ms-client-request-id" : "b81ff58c-a870-41cc-87f5-17c555b9377d",
"Content-Type" : "application/xml; charset=utf-8"
},
"Response" : {
"x-ms-version" : "2019-07-07",
"Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
"retry-after" : "0",
"Content-Length" : "0",
"StatusCode" : "202",
"x-ms-request-id" : "b3ac340f-701e-00b0-76b1-28ad54000000",
"Date" : "Tue, 12 May 2020 23:03:14 GMT",
"x-ms-client-request-id" : "b81ff58c-a870-41cc-87f5-17c555b9377d"
},
"Exception" : null
}, {
"Method" : "GET",
"Uri" : "https://REDACTED.blob.core.windows.net?restype=service&comp=properties",
"Headers" : {
"x-ms-version" : "2019-07-07",
"User-Agent" : "azsdk-java-azure-storage-blob/12.7.0-beta.1 (11.0.6; Windows 10 10.0)",
"x-ms-client-request-id" : "bab4afc0-9073-4c56-ad5f-94919ba10bbf"
},
"Response" : {
"Transfer-Encoding" : "chunked",
"x-ms-version" : "2019-07-07",
"Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
"retry-after" : "0",
"StatusCode" : "200",
"x-ms-request-id" : "4c6ba48a-d01e-0018-53b1-2854e0000000",
"Body" : "<?xml version=\"1.0\" encoding=\"utf-8\"?><StorageServiceProperties><Logging><Version>1.0</Version><Read>false</Read><Write>false</Write><Delete>false</Delete><RetentionPolicy><Enabled>false</Enabled></RetentionPolicy></Logging><HourMetrics><Version>1.0</Version><Enabled>false</Enabled><RetentionPolicy><Enabled>false</Enabled></RetentionPolicy></HourMetrics><MinuteMetrics><Version>1.0</Version><Enabled>false</Enabled><RetentionPolicy><Enabled>false</Enabled></RetentionPolicy></MinuteMetrics><Cors /><DeleteRetentionPolicy><Enabled>false</Enabled></DeleteRetentionPolicy><StaticWebsite><Enabled>false</Enabled></StaticWebsite><DefaultServiceVersion>2018-03-28</DefaultServiceVersion></StorageServiceProperties>",
"Date" : "Tue, 12 May 2020 23:03:18 GMT",
"x-ms-client-request-id" : "bab4afc0-9073-4c56-ad5f-94919ba10bbf",
"Content-Type" : "application/xml"
},
"Exception" : null
}, {
"Method" : "PUT",
"Uri" : "https://REDACTED.blob.core.windows.net?restype=service&comp=properties",
"Headers" : {
"x-ms-version" : "2019-07-07",
"User-Agent" : "azsdk-java-azure-storage-blob/12.7.0-beta.1 (11.0.6; Windows 10 10.0)",
"x-ms-client-request-id" : "a027d75a-04a3-401d-9c83-a1ad661b1dce",
"Content-Type" : "application/xml; charset=utf-8"
},
"Response" : {
"x-ms-version" : "2019-07-07",
"Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
"retry-after" : "0",
"Content-Length" : "0",
"StatusCode" : "202",
"x-ms-request-id" : "92b1f0d3-401e-0134-40b1-28bd29000000",
"Date" : "Tue, 12 May 2020 23:03:21 GMT",
"x-ms-client-request-id" : "a027d75a-04a3-401d-9c83-a1ad661b1dce"
},
"Exception" : null
}, {
"Method" : "GET",
"Uri" : "https://REDACTED.blob.core.windows.net?prefix=jtcoauthonsecondary&comp=list",
"Headers" : {
"x-ms-version" : "2019-07-07",
"User-Agent" : "azsdk-java-azure-storage-blob/12.7.0-beta.1 (11.0.6; Windows 10 10.0)",
"x-ms-client-request-id" : "fa58d8a9-7dfa-4b4a-a1f6-4198f00dd99d"
},
"Response" : {
"Transfer-Encoding" : "chunked",
"x-ms-version" : "2019-07-07",
"Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
"retry-after" : "0",
"StatusCode" : "200",
"x-ms-request-id" : "94b82baf-b01e-002e-64b1-28d413000000",
"Body" : "<?xml version=\"1.0\" encoding=\"utf-8\"?><EnumerationResults ServiceEndpoint=\"https://xclientdev3.blob.core.windows.net/\"><Prefix>jtcoauthonsecondary</Prefix><Containers><Container><Name>jtcoauthonsecondary0serviceapitestoauthonsecondaryc61119591f</Name><Properties><Last-Modified>Tue, 12 May 2020 23:03:11 GMT</Last-Modified><Etag>\"0x8D7F6C8A508947E\"</Etag><LeaseStatus>unlocked</LeaseStatus><LeaseState>available</LeaseState><DefaultEncryptionScope>$account-encryption-key</DefaultEncryptionScope><DenyEncryptionScopeOverride>false</DenyEncryptionScopeOverride><HasImmutabilityPolicy>false</HasImmutabilityPolicy><HasLegalHold>false</HasLegalHold></Properties></Container></Containers><NextMarker /></EnumerationResults>",
"Date" : "Tue, 12 May 2020 23:03:21 GMT",
"x-ms-client-request-id" : "fa58d8a9-7dfa-4b4a-a1f6-4198f00dd99d",
"Content-Type" : "application/xml"
},
"Exception" : null
}, {
"Method" : "DELETE",
"Uri" : "https://REDACTED.blob.core.windows.net/jtcoauthonsecondary0serviceapitestoauthonsecondaryc61119591f?restype=container",
"Headers" : {
"x-ms-version" : "2019-07-07",
"User-Agent" : "azsdk-java-azure-storage-blob/12.7.0-beta.1 (11.0.6; Windows 10 10.0)",
"x-ms-client-request-id" : "944ffd2e-8d67-4c8c-8b79-e325567a3b06"
},
"Response" : {
"x-ms-version" : "2019-07-07",
"Server" : "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0",
"retry-after" : "0",
"Content-Length" : "0",
"StatusCode" : "202",
"x-ms-request-id" : "826a6e51-301e-0095-26b1-2835e7000000",
"Date" : "Tue, 12 May 2020 23:03:22 GMT",
"x-ms-client-request-id" : "944ffd2e-8d67-4c8c-8b79-e325567a3b06"
},
"Exception" : null
} ],
"variables" : [ "jtcoauthonsecondary0serviceapitestoauthonsecondaryc61119591f" ]
}

0 comments on commit f35a9b1

Please sign in to comment.