diff --git a/sdk/azidentity/azidentity.go b/sdk/azidentity/azidentity.go index 5be975682348..d063603e35f7 100644 --- a/sdk/azidentity/azidentity.go +++ b/sdk/azidentity/azidentity.go @@ -59,8 +59,8 @@ var getConfidentialClient = func(clientID, tenantID string, cred confidential.Cr if err != nil { return confidential.Client{}, err } + authority := runtime.JoinPaths(authorityHost, tenantID) o := []confidential.Option{ - confidential.WithAuthority(runtime.JoinPaths(authorityHost, tenantID)), confidential.WithAzureRegion(os.Getenv(azureRegionalAuthorityName)), confidential.WithHTTPClient(newPipelineAdapter(co)), } @@ -71,7 +71,7 @@ var getConfidentialClient = func(clientID, tenantID string, cred confidential.Cr if strings.ToLower(tenantID) == "adfs" { o = append(o, confidential.WithInstanceDiscovery(false)) } - return confidential.New(clientID, cred, o...) + return confidential.New(authority, clientID, cred, o...) } var getPublicClient = func(clientID, tenantID string, co *azcore.ClientOptions, additionalOpts ...public.Option) (public.Client, error) { @@ -93,9 +93,7 @@ var getPublicClient = func(clientID, tenantID string, co *azcore.ClientOptions, if strings.ToLower(tenantID) == "adfs" { o = append(o, public.WithInstanceDiscovery(false)) } - return public.New(clientID, - o..., - ) + return public.New(clientID, o...) } // resolveAdditionallyAllowedTenants returns a copy of tenants, simplified when tenants contains a wildcard diff --git a/sdk/azidentity/client_certificate_credential.go b/sdk/azidentity/client_certificate_credential.go index 16bed018b276..599ea60718dd 100644 --- a/sdk/azidentity/client_certificate_credential.go +++ b/sdk/azidentity/client_certificate_credential.go @@ -52,7 +52,7 @@ func NewClientCertificateCredential(tenantID string, clientID string, certs []*x if options == nil { options = &ClientCertificateCredentialOptions{} } - cred, err := confidential.NewCredFromCertChain(certs, key) + cred, err := confidential.NewCredFromCert(certs, key) if err != nil { return nil, err } diff --git a/sdk/azidentity/go.mod b/sdk/azidentity/go.mod index 2a7c5a3e3d72..611dbf294a20 100644 --- a/sdk/azidentity/go.mod +++ b/sdk/azidentity/go.mod @@ -3,22 +3,22 @@ module github.com/Azure/azure-sdk-for-go/sdk/azidentity go 1.18 require ( - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0-beta.1 + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.5.0-beta.1 github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2 - github.com/AzureAD/microsoft-authentication-library-for-go v0.8.1 - github.com/golang-jwt/jwt/v4 v4.4.2 + github.com/AzureAD/microsoft-authentication-library-for-go v0.9.0 + github.com/golang-jwt/jwt/v4 v4.4.3 golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/dnaeon/go-vcr v1.1.0 // indirect - github.com/google/uuid v1.1.1 // indirect + github.com/google/uuid v1.3.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect - github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4 // indirect - golang.org/x/net v0.5.0 // indirect - golang.org/x/sys v0.4.0 // indirect - golang.org/x/text v0.6.0 // indirect + github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect + golang.org/x/net v0.7.0 // indirect + golang.org/x/sys v0.5.0 // indirect + golang.org/x/text v0.7.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) diff --git a/sdk/azidentity/go.sum b/sdk/azidentity/go.sum index 1c6d2a75dbfe..bd0510dad755 100644 --- a/sdk/azidentity/go.sum +++ b/sdk/azidentity/go.sum @@ -1,32 +1,33 @@ -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0-beta.1 h1:gwgeyp9Xp0tqcSa1vLyMlem4UK5WGEHLAEi34dUVI+Q= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0-beta.1/go.mod h1:DffdKW9RFqa5VgmsjUOsS7UE7eiA5iAvYUs63bhKQ0M= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.5.0-beta.1 h1:yLM4ZIC+NRvzwFGpXjUbf5FhPBVxJgmYXkjePgNAx64= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.5.0-beta.1/go.mod h1:ON4tFdPTwRcgWEaVDrN3584Ef+b7GgSJaXxe5fW9t4M= github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2 h1:+5VZ72z0Qan5Bog5C+ZkgSqUbeVUd9wgtHOrIKuc5b8= github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= -github.com/AzureAD/microsoft-authentication-library-for-go v0.8.1 h1:oPdPEZFSbl7oSPEAIPMPBMUmiL+mqgzBJwM/9qYcwNg= -github.com/AzureAD/microsoft-authentication-library-for-go v0.8.1/go.mod h1:4qFor3D/HDsvBME35Xy9rwW9DecL+M2sNw1ybjPtwA0= +github.com/AzureAD/microsoft-authentication-library-for-go v0.9.0 h1:UE9n9rkJF62ArLb1F3DEjRt8O3jLwMWdSoypKV4f3MU= +github.com/AzureAD/microsoft-authentication-library-for-go v0.9.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dnaeon/go-vcr v1.1.0 h1:ReYa/UBrRyQdant9B4fNHGoCNKw6qh6P0fsdGmZpR7c= github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= -github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs= -github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/golang-jwt/jwt/v4 v4.4.3 h1:Hxl6lhQFj4AnOX6MLrsCb/+7tCj7DxP7VA+2rDIq5AU= +github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= -github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4 h1:Qj1ukM4GlMWXNdMBuXcXfz/Kw9s1qm0CLY32QxuSImI= -github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88 h1:Tgea0cVUD0ivh5ADBX4WwuI12DUd2to3nCYe2eayMIw= golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= -golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/sdk/azidentity/managed_identity_credential.go b/sdk/azidentity/managed_identity_credential.go index 3a64628b63a1..1528a78f2460 100644 --- a/sdk/azidentity/managed_identity_credential.go +++ b/sdk/azidentity/managed_identity_credential.go @@ -92,7 +92,8 @@ func NewManagedIdentityCredential(options *ManagedIdentityCredentialOptions) (*M if options.ID != nil { clientID = options.ID.String() } - c, err := confidential.New(clientID, cred) + // similarly, it's okay to give MSAL an incorrect authority URL because that URL won't be used + c, err := confidential.New("https://login.microsoftonline.com/common", clientID, cred) if err != nil { return nil, err } diff --git a/sdk/azidentity/on_behalf_of_credential.go b/sdk/azidentity/on_behalf_of_credential.go index a18e9adc4c3c..d7f9081656f5 100644 --- a/sdk/azidentity/on_behalf_of_credential.go +++ b/sdk/azidentity/on_behalf_of_credential.go @@ -50,7 +50,7 @@ type OnBehalfOfCredentialOptions struct { // NewOnBehalfOfCredentialFromCertificate constructs an OnBehalfOfCredential that authenticates with a certificate. // See [ParseCertificates] for help loading a certificate. func NewOnBehalfOfCredentialFromCertificate(tenantID, clientID, userAssertion string, certs []*x509.Certificate, key crypto.PrivateKey, options *OnBehalfOfCredentialOptions) (*OnBehalfOfCredential, error) { - cred, err := confidential.NewCredFromCertChain(certs, key) + cred, err := confidential.NewCredFromCert(certs, key) if err != nil { return nil, err } diff --git a/sdk/azidentity/on_behalf_of_credential_test.go b/sdk/azidentity/on_behalf_of_credential_test.go index bd35cd860d78..65b27c773fbb 100644 --- a/sdk/azidentity/on_behalf_of_credential_test.go +++ b/sdk/azidentity/on_behalf_of_credential_test.go @@ -8,12 +8,12 @@ package azidentity import ( "context" + "net/http" + "strings" "testing" "time" - "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" - "github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential" ) func TestOnBehalfOfCredential(t *testing.T) { @@ -21,68 +21,55 @@ func TestOnBehalfOfCredential(t *testing.T) { t.Cleanup(func() { getConfidentialClient = realGetClient }) expectedAssertion := "user-assertion" for _, test := range []struct { - ctor func() (*OnBehalfOfCredential, error) + ctor func(policy.Transporter) (*OnBehalfOfCredential, error) name string sendX5C bool }{ { - ctor: func() (*OnBehalfOfCredential, error) { + ctor: func(tp policy.Transporter) (*OnBehalfOfCredential, error) { certs, key := allCertTests[0].certs, allCertTests[0].key - return NewOnBehalfOfCredentialFromCertificate(fakeTenantID, fakeClientID, expectedAssertion, certs, key, nil) + o := OnBehalfOfCredentialOptions{ClientOptions: policy.ClientOptions{Transport: tp}} + return NewOnBehalfOfCredentialFromCertificate(fakeTenantID, fakeClientID, expectedAssertion, certs, key, &o) }, name: "certificate", }, { - ctor: func() (*OnBehalfOfCredential, error) { + ctor: func(tp policy.Transporter) (*OnBehalfOfCredential, error) { certs, key := allCertTests[0].certs, allCertTests[0].key - return NewOnBehalfOfCredentialFromCertificate(fakeTenantID, fakeClientID, expectedAssertion, certs, key, &OnBehalfOfCredentialOptions{SendCertificateChain: true}) + o := OnBehalfOfCredentialOptions{ClientOptions: policy.ClientOptions{Transport: tp}, SendCertificateChain: true} + return NewOnBehalfOfCredentialFromCertificate(fakeTenantID, fakeClientID, expectedAssertion, certs, key, &o) }, - name: "certificate_SNI", + name: "SNI", sendX5C: true, }, { - ctor: func() (*OnBehalfOfCredential, error) { - return NewOnBehalfOfCredentialFromSecret(fakeTenantID, fakeClientID, expectedAssertion, "secret", nil) + ctor: func(tp policy.Transporter) (*OnBehalfOfCredential, error) { + o := OnBehalfOfCredentialOptions{ClientOptions: policy.ClientOptions{Transport: tp}} + return NewOnBehalfOfCredentialFromSecret(fakeTenantID, fakeClientID, expectedAssertion, "secret", &o) }, name: "secret", }, } { t.Run(test.name, func(t *testing.T) { - called := false key := struct{}{} ctx := context.WithValue(context.Background(), key, true) - fake := fakeConfidentialClient{ - ar: confidential.AuthResult{AccessToken: tokenValue, ExpiresOn: time.Now().Add(time.Hour)}, - oboCallback: func(c context.Context, assertion string, scopes []string) { - called = true - if v := c.Value(key); v == nil || !v.(bool) { - t.Error("AcquireTokenOnBehalfOf received unexpected Context") - } - if len(scopes) != 1 || scopes[0] != liveTestScope { - t.Errorf(`unexpected scopes "%v"`, scopes) - } - if assertion != expectedAssertion { - t.Errorf(`unexpected assertion "%s"`, assertion) - } - }, - } - getConfidentialClient = func(clientID, tenantID string, cred confidential.Credential, co *azcore.ClientOptions, opts ...confidential.Option) (confidentialClient, error) { - if clientID != fakeClientID { - t.Errorf(`unexpected clientID "%s"`, clientID) + srv := mockSTS{tokenRequestCallback: func(r *http.Request) { + if c := r.Context(); c == nil { + t.Fatal("AcquireTokenOnBehalfOf received no Context") + } else if v := c.Value(key); v == nil || !v.(bool) { + t.Fatal("AcquireTokenOnBehalfOf received unexpected Context") } - if tenantID != fakeTenantID { - t.Errorf(`unexpected tenantID "%s"`, tenantID) + if err := r.ParseForm(); err != nil { + t.Fatal(err) } - msalOpts := confidential.Options{} - for _, o := range opts { - o(&msalOpts) + if scope := r.FormValue("scope"); !strings.Contains(scope, liveTestScope) { + t.Errorf(`unexpected scopes "%v"`, scope) } - if test.sendX5C != msalOpts.SendX5C { - t.Fatal("incorrect value for SendX5C") + if assertion := r.FormValue("assertion"); assertion != expectedAssertion { + t.Errorf(`unexpected assertion "%s"`, assertion) } - return fake, nil - } - cred, err := test.ctor() + }} + cred, err := test.ctor(&srv) if err != nil { t.Fatal(err) } @@ -99,9 +86,6 @@ func TestOnBehalfOfCredential(t *testing.T) { if tk.ExpiresOn.Location() != time.UTC { t.Error("ExpiresOn isn't UTC") } - if !called { - t.Fatal("validation function wasn't called") - } }) } }