Skip to content

Commit 6316e3b

Browse files
authored
Don't panic on a nil credential value (Azure#21835)
Just skip the authorization step.
1 parent b7dce8a commit 6316e3b

File tree

7 files changed

+75
-10
lines changed

7 files changed

+75
-10
lines changed

sdk/azcore/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
* Include error text instead of error type in traces when the transport returns an error.
1515
* Fixed an issue that could cause an HTTP/2 request to hang when the TCP connection becomes unresponsive.
1616
* Block key and SAS authentication for non TLS protected endpoints.
17+
* Passing a `nil` credential value will no longer cause a panic. Instead, the authentication is skipped.
1718

1819
### Other Changes
1920

sdk/azcore/runtime/policy_bearer_token.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,17 @@ func (b *BearerTokenPolicy) authenticateAndAuthorize(req *policy.Request) func(p
7272

7373
// Do authorizes a request with a bearer token
7474
func (b *BearerTokenPolicy) Do(req *policy.Request) (*http.Response, error) {
75+
// skip adding the authorization header if no TokenCredential was provided.
76+
// this prevents a panic that might be hard to diagnose and allows testing
77+
// against http endpoints that don't require authentication.
78+
if b.cred == nil {
79+
return req.Next()
80+
}
81+
7582
if err := checkHTTPSForAuth(req); err != nil {
7683
return nil, err
7784
}
85+
7886
var err error
7987
if b.authzHandler.OnRequest != nil {
8088
err = b.authzHandler.OnRequest(req, b.authenticateAndAuthorize(req))

sdk/azcore/runtime/policy_bearer_token_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,3 +246,15 @@ func TestCheckHTTPSForAuth(t *testing.T) {
246246
require.NoError(t, err)
247247
require.NoError(t, checkHTTPSForAuth(req))
248248
}
249+
250+
func TestBearerTokenPolicy_NilCredential(t *testing.T) {
251+
policy := NewBearerTokenPolicy(nil, nil, nil)
252+
pl := exported.NewPipeline(shared.TransportFunc(func(req *http.Request) (*http.Response, error) {
253+
require.Zero(t, req.Header.Get(shared.HeaderAuthorization))
254+
return &http.Response{}, nil
255+
}), policy)
256+
req, err := NewRequest(context.Background(), "GET", "http://contoso.com")
257+
require.NoError(t, err)
258+
_, err = pl.Do(req)
259+
require.NoError(t, err)
260+
}

sdk/azcore/runtime/policy_key_credential.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,18 @@ func NewKeyCredentialPolicy(cred *exported.KeyCredential, header string, options
4040

4141
// Do implementes the Do method on the [policy.Polilcy] interface.
4242
func (k *KeyCredentialPolicy) Do(req *policy.Request) (*http.Response, error) {
43-
if err := checkHTTPSForAuth(req); err != nil {
44-
return nil, err
43+
// skip adding the authorization header if no KeyCredential was provided.
44+
// this prevents a panic that might be hard to diagnose and allows testing
45+
// against http endpoints that don't require authentication.
46+
if k.cred != nil {
47+
if err := checkHTTPSForAuth(req); err != nil {
48+
return nil, err
49+
}
50+
val := exported.KeyCredentialGet(k.cred)
51+
if k.prefix != "" {
52+
val = k.prefix + val
53+
}
54+
req.Raw().Header.Add(k.header, val)
4555
}
46-
val := exported.KeyCredentialGet(k.cred)
47-
if k.prefix != "" {
48-
val = k.prefix + val
49-
}
50-
req.Raw().Header.Add(k.header, val)
5156
return req.Next()
5257
}

sdk/azcore/runtime/policy_key_credential_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,20 @@ func TestKeyCredentialPolicy_RequiresHTTPS(t *testing.T) {
6565
_, err = pl.Do(req)
6666
require.Error(t, err)
6767
}
68+
69+
func TestKeyCredentialPolicy_NilCredential(t *testing.T) {
70+
const headerName = "fake-auth"
71+
policy := NewKeyCredentialPolicy(nil, headerName, nil)
72+
require.NotNil(t, policy)
73+
74+
pl := exported.NewPipeline(shared.TransportFunc(func(req *http.Request) (*http.Response, error) {
75+
require.Zero(t, req.Header.Get(headerName))
76+
return &http.Response{}, nil
77+
}), policy)
78+
79+
req, err := NewRequest(context.Background(), http.MethodGet, "http://contoso.com")
80+
require.NoError(t, err)
81+
82+
_, err = pl.Do(req)
83+
require.NoError(t, err)
84+
}

sdk/azcore/runtime/policy_sas_credential.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,14 @@ func NewSASCredentialPolicy(cred *exported.SASCredential, header string, options
3434

3535
// Do implementes the Do method on the [policy.Polilcy] interface.
3636
func (k *SASCredentialPolicy) Do(req *policy.Request) (*http.Response, error) {
37-
if err := checkHTTPSForAuth(req); err != nil {
38-
return nil, err
37+
// skip adding the authorization header if no SASCredential was provided.
38+
// this prevents a panic that might be hard to diagnose and allows testing
39+
// against http endpoints that don't require authentication.
40+
if k.cred != nil {
41+
if err := checkHTTPSForAuth(req); err != nil {
42+
return nil, err
43+
}
44+
req.Raw().Header.Add(k.header, exported.SASCredentialGet(k.cred))
3945
}
40-
req.Raw().Header.Add(k.header, exported.SASCredentialGet(k.cred))
4146
return req.Next()
4247
}

sdk/azcore/runtime/policy_sas_credential_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,20 @@ func TestSASCredentialPolicy_RequiresHTTPS(t *testing.T) {
4949
_, err = pl.Do(req)
5050
require.Error(t, err)
5151
}
52+
53+
func TestSASCredentialPolicy_NilCredential(t *testing.T) {
54+
const headerName = "fake-auth"
55+
policy := NewSASCredentialPolicy(nil, headerName, nil)
56+
require.NotNil(t, policy)
57+
58+
pl := exported.NewPipeline(shared.TransportFunc(func(req *http.Request) (*http.Response, error) {
59+
require.Zero(t, req.Header.Get(headerName))
60+
return &http.Response{}, nil
61+
}), policy)
62+
63+
req, err := NewRequest(context.Background(), http.MethodGet, "http://contoso.com")
64+
require.NoError(t, err)
65+
66+
_, err = pl.Do(req)
67+
require.NoError(t, err)
68+
}

0 commit comments

Comments
 (0)