|  | 
| 3 | 3 | 
 | 
| 4 | 4 | using System; | 
| 5 | 5 | using System.Diagnostics; | 
| 6 |  | -using System.Diagnostics.Tracing; | 
| 7 | 6 | using System.IO; | 
| 8 | 7 | using System.Text; | 
| 9 | 8 | using System.Text.Json; | 
| 10 | 9 | using System.Text.RegularExpressions; | 
| 11 | 10 | using System.Threading; | 
| 12 | 11 | using System.Threading.Tasks; | 
| 13 | 12 | using Azure.Core; | 
| 14 |  | -using Azure.Core.Diagnostics; | 
| 15 | 13 | using Azure.Core.Pipeline; | 
| 16 | 14 | using Azure.Core.TestFramework; | 
| 17 | 15 | using Azure.Security.KeyVault.Tests; | 
| 18 | 16 | using NUnit.Framework; | 
| 19 | 17 | 
 | 
| 20 | 18 | namespace Azure.Security.KeyVault.Secrets.Tests | 
| 21 | 19 | { | 
|  | 20 | +    [NonParallelizable] | 
| 22 | 21 |     public class ChallengeBasedAuthenticationPolicyTests | 
| 23 | 22 |     { | 
| 24 | 23 |         private const string TenantId = "72f988bf-86f1-41af-91ab-2d7cd011db47"; | 
| 25 | 24 |         private const string VaultHost = "test.vault.azure.net"; | 
| 26 | 25 | 
 | 
| 27 | 26 |         private static Uri VaultUri => new Uri("https://" + VaultHost); | 
| 28 | 27 | 
 | 
|  | 28 | +        [SetUp] | 
|  | 29 | +        public void Setup() | 
|  | 30 | +        { | 
|  | 31 | +            ChallengeBasedAuthenticationPolicy.ClearCache(); | 
|  | 32 | +        } | 
|  | 33 | + | 
| 29 | 34 |         [Test] | 
| 30 | 35 |         public async Task SingleRequest() | 
| 31 | 36 |         { | 
| @@ -122,6 +127,78 @@ public async Task TenantChangedRequest() | 
| 122 | 127 |             } | 
| 123 | 128 |         } | 
| 124 | 129 | 
 | 
|  | 130 | +        [Test] | 
|  | 131 | +        public async Task ReauthenticatesWhenTenantChanged() | 
|  | 132 | +        { | 
|  | 133 | +            MockTransport transport = new(new[] | 
|  | 134 | +            { | 
|  | 135 | +                // Initial tenant. | 
|  | 136 | +                new MockResponse(401) | 
|  | 137 | +                    .WithHeader("WWW-Authenticate", @"Bearer authorization=""https://login.windows.net/de763a21-49f7-4b08-a8e1-52c8fbc103b4"", resource=""https://vault.azure.net"""), | 
|  | 138 | + | 
|  | 139 | +                new MockResponse(200) | 
|  | 140 | +                    .WithJson(""" | 
|  | 141 | +                    { | 
|  | 142 | +                        "token_type": "Bearer", | 
|  | 143 | +                        "expires_in": 3599, | 
|  | 144 | +                        "resource": "https://vault.azure.net", | 
|  | 145 | +                        "access_token": "ZGU3NjNhMjEtNDlmNy00YjA4LWE4ZTEtNTJjOGZiYzEwM2I0" | 
|  | 146 | +                    } | 
|  | 147 | +                    """), | 
|  | 148 | + | 
|  | 149 | +                new MockResponse(200) | 
|  | 150 | +                { | 
|  | 151 | +                    ContentStream = new KeyVaultSecret("test-secret", "secret-value").ToStream(), | 
|  | 152 | +                }, | 
|  | 153 | + | 
|  | 154 | +                // Moved tenants. | 
|  | 155 | +                new MockResponse(401) | 
|  | 156 | +                    .WithHeader("WWW-Authenticate", @"Bearer authorization=""https://login.windows.net/72f988bf-86f1-41af-91ab-2d7cd011db47"", resource=""https://vault.azure.net""") | 
|  | 157 | +                    .WithJson(""" | 
|  | 158 | +                    { | 
|  | 159 | +                        "error": { | 
|  | 160 | +                            "code": "Unauthorized", | 
|  | 161 | +                            "message": "AKV10032: Invalid issuer. Expected one of https://sts.windows.net/72f988bf-86f1-41af-91ab-2d7cd011db47/, https://sts.windows.net/f8cdef31-a31e-4b4a-93e4-5f571e91255a/, https://sts.windows.net/e2d54eb5-3869-4f70-8578-dee5fc7331f4/, https://sts.windows.net/33e01921-4d64-4f8c-a055-5bdaffd5e33d/, https://sts.windows.net/975f013f-7f24-47e8-a7d3-abc4752bf346/, found https://sts.windows.net/96be4b7a-defb-4dc2-a31f-49ee6145d5ab/." | 
|  | 162 | +                        } | 
|  | 163 | +                    } | 
|  | 164 | +                    """), | 
|  | 165 | + | 
|  | 166 | +                new MockResponse(200) | 
|  | 167 | +                    .WithJson(""" | 
|  | 168 | +                    { | 
|  | 169 | +                        "token_type": "Bearer", | 
|  | 170 | +                        "expires_in": 3599, | 
|  | 171 | +                        "resource": "https://vault.azure.net", | 
|  | 172 | +                        "access_token": "NzJmOTg4YmYtODZmMS00MWFmLTkxYWItMmQ3Y2QwMTFkYjQ3" | 
|  | 173 | +                    } | 
|  | 174 | +                    """), | 
|  | 175 | + | 
|  | 176 | +                new MockResponse(200) | 
|  | 177 | +                { | 
|  | 178 | +                    ContentStream = new KeyVaultSecret("test-secret", "secret-value").ToStream(), | 
|  | 179 | +                }, | 
|  | 180 | +            }); | 
|  | 181 | + | 
|  | 182 | +            SecretClientOptions options = new() | 
|  | 183 | +            { | 
|  | 184 | +                Transport = transport, | 
|  | 185 | +            }; | 
|  | 186 | + | 
|  | 187 | +            SecretClient client = new( | 
|  | 188 | +                VaultUri, | 
|  | 189 | +                new MockCredential(transport), | 
|  | 190 | +                options); | 
|  | 191 | + | 
|  | 192 | +            Response<KeyVaultSecret> response = await client.GetSecretAsync("test-secret"); | 
|  | 193 | +            Assert.AreEqual(200, response.GetRawResponse().Status); | 
|  | 194 | +            Assert.AreEqual("secret-value", response.Value.Value); | 
|  | 195 | + | 
|  | 196 | +            // Try it again now that the vault should have moved tenants. | 
|  | 197 | +            response = await client.GetSecretAsync("test-secret"); | 
|  | 198 | +            Assert.AreEqual(200, response.GetRawResponse().Status); | 
|  | 199 | +            Assert.AreEqual("secret-value", response.Value.Value); | 
|  | 200 | +        } | 
|  | 201 | + | 
| 125 | 202 |         private class MockTransportBuilder | 
| 126 | 203 |         { | 
| 127 | 204 |             private const string AuthorizationHeader = "Authorization"; | 
|  | 
0 commit comments