Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Use correct scope for Entra authentication #198

Merged
merged 1 commit into from
May 30, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 22 additions & 17 deletions azuread/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ package azuread

import (
"context"
"crypto"
"crypto/x509"
"errors"
"fmt"
"os"
Expand Down Expand Up @@ -75,23 +77,23 @@ func parse(dsn string) (*azureFedAuthConfig, error) {

func (p *azureFedAuthConfig) validateParameters(params map[string]string) error {

fedAuthWorkflow, _ := params["fedauth"]
fedAuthWorkflow := params["fedauth"]
if fedAuthWorkflow == "" {
return nil
}

p.fedAuthLibrary = mssql.FedAuthLibraryADAL

p.applicationClientID, _ = params["applicationclientid"]
p.applicationClientID = params["applicationclientid"]

switch {
case strings.EqualFold(fedAuthWorkflow, ActiveDirectoryPassword):
if p.applicationClientID == "" {
return errors.New("applicationclientid parameter is required for " + ActiveDirectoryPassword)
}
p.adalWorkflow = mssql.FedAuthADALWorkflowPassword
p.user, _ = params["user id"]
p.password, _ = params["password"]
p.user = params["user id"]
p.password = params["password"]
case strings.EqualFold(fedAuthWorkflow, ActiveDirectoryIntegrated):
// Active Directory Integrated authentication is not fully supported:
// you can only use this by also implementing an a token provider
Expand All @@ -101,7 +103,7 @@ func (p *azureFedAuthConfig) validateParameters(params map[string]string) error
// When using MSI, to request a specific client ID or user-assigned identity,
// provide the ID in the "user id" parameter
p.adalWorkflow = mssql.FedAuthADALWorkflowMSI
p.resourceID, _ = params["resource id"]
p.resourceID = params["resource id"]
p.clientID, _ = splitTenantAndClientID(params["user id"])
case strings.EqualFold(fedAuthWorkflow, ActiveDirectoryApplication) || strings.EqualFold(fedAuthWorkflow, ActiveDirectoryServicePrincipal):
p.adalWorkflow = mssql.FedAuthADALWorkflowPassword
Expand All @@ -112,9 +114,9 @@ func (p *azureFedAuthConfig) validateParameters(params map[string]string) error
return errors.New("Must provide 'client id[@tenant id]' as username parameter when using ActiveDirectoryApplication authentication")
}

p.clientSecret, _ = params["password"]
p.clientSecret = params["password"]

p.certificatePath, _ = params["clientcertpath"]
p.certificatePath = params["clientcertpath"]

if p.certificatePath == "" && p.clientSecret == "" {
return errors.New("Must provide 'password' parameter when using ActiveDirectoryApplication authentication without cert/key credentials")
Expand All @@ -126,13 +128,13 @@ func (p *azureFedAuthConfig) validateParameters(params map[string]string) error
return errors.New("applicationclientid parameter is required for " + ActiveDirectoryInteractive)
}
// user is an optional login hint
p.user, _ = params["user id"]
p.user = params["user id"]
// we don't really have a password but we need to use some value.
p.adalWorkflow = mssql.FedAuthADALWorkflowPassword
case strings.EqualFold(fedAuthWorkflow, ActiveDirectoryServicePrincipalAccessToken):
p.fedAuthLibrary = mssql.FedAuthLibrarySecurityToken
p.adalWorkflow = mssql.FedAuthADALWorkflowNone
p.password, _ = params["password"]
p.password = params["password"]

if p.password == "" {
return errors.New("Must provide 'password' parameter when using ActiveDirectoryServicePrincipalAccessToken authentication")
Expand All @@ -156,10 +158,10 @@ func splitTenantAndClientID(user string) (string, string) {
return user[0:at], user[at+1:]
}

func splitAuthorityAndTenant(authorityUrl string) (string, string) {
separatorIndex := strings.LastIndex(authorityUrl, "/")
tenant := authorityUrl[separatorIndex+1:]
authority := authorityUrl[:separatorIndex]
func splitAuthorityAndTenant(authorityURL string) (string, string) {
separatorIndex := strings.LastIndex(authorityURL, "/")
tenant := authorityURL[separatorIndex+1:]
authority := authorityURL[:separatorIndex]
return authority, tenant
}

Expand All @@ -171,18 +173,21 @@ func (p *azureFedAuthConfig) provideActiveDirectoryToken(ctx context.Context, se
if p.tenantID != "" {
tenant = p.tenantID
}
scope := stsURL
scope := serverSPN
if !strings.HasSuffix(serverSPN, scopeDefaultSuffix) {
scope = strings.TrimRight(serverSPN, "/") + scopeDefaultSuffix
scope = serverSPN + scopeDefaultSuffix
}

switch p.fedAuthWorkflow {
case ActiveDirectoryServicePrincipal, ActiveDirectoryApplication:
switch {
case p.certificatePath != "":
certData, err := os.ReadFile(p.certificatePath)
var certData []byte
certData, err = os.ReadFile(p.certificatePath)
if err != nil {
certs, key, err := azidentity.ParseCertificates(certData, []byte(p.clientSecret))
var certs []*x509.Certificate
var key crypto.PrivateKey
certs, key, err = azidentity.ParseCertificates(certData, []byte(p.clientSecret))
if err != nil {
cred, err = azidentity.NewClientCertificateCredential(tenant, p.clientID, certs, key, nil)
}
Expand Down
Loading