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

sso-auth: Azure AD provider #118

Open
wants to merge 39 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
c3ae45d
First pass port of Azure v2 provider
sporkmonger Oct 5, 2018
5acfd70
Porting of Azure AD provider largely complete
sporkmonger Nov 15, 2018
83e43a1
Fix group tests, add sign-in tests, and generate nonces
sporkmonger Nov 16, 2018
4e51eae
Add golang-lru to Godeps
sporkmonger Nov 16, 2018
413d831
Expand abbreviation in comment
Jan 8, 2019
3fcdff4
Update documentation and compile time checking of provider interface
Jan 9, 2019
315d1bd
Update Azure provider constant for consistency
Jan 9, 2019
38d0523
Fix up comments related to common default tenant ID
Jan 9, 2019
4f8b330
Document odata pagination hyperlinking
Jan 9, 2019
23e5067
Remove unused helper function
Jan 9, 2019
97957bc
Remove unused contains helper function
Jan 9, 2019
70b7c20
Removed commented out code
Jan 9, 2019
0d4d57e
Remove unnecessary new line from comment
Jan 9, 2019
837ad42
Switch things to package private that don't need to be exported
Jan 9, 2019
82c429b
Fix return value on error
Jan 9, 2019
bd344fe
This API should only return 200 on success
Jan 9, 2019
e0e9804
Consistent mutex variable names
Jan 9, 2019
5234346
This API should only return 200 on success
Jan 9, 2019
515bb6a
Make it clearer that this is a template value
Jan 9, 2019
359275b
Drop usage of named return values
Jan 9, 2019
0ff780c
Update comments to accurately reflect what's happening in Marshal/Unm…
Jan 9, 2019
91b3768
Drop another usage of named return values
Jan 9, 2019
dfc5040
Combine cache lookup and success check into a single if statement
Jan 9, 2019
e786df6
Add explanatory text to interface comments to highlight purpose in mocks
Jan 9, 2019
ce8b2d0
Drop debug logging lines
Jan 12, 2019
759506e
Switch from HMAC to AEAD to simplify nonce validation
Jan 12, 2019
1f06ed2
Rename to ms_graph_api.go and add top-level comment
Jan 12, 2019
fcf4c96
Move generic OIDC discovery logic into generic OIDC provider
Jan 15, 2019
d19cddf
Add clarification around error handling
Jan 15, 2019
55d4776
Update mock file to match rename of graph service struct
Jan 18, 2019
fd7b43f
Remove methods again
Jan 19, 2019
4c8c289
Remove debug lines
Jan 19, 2019
b95cb54
Get sign out working
Jan 30, 2019
b5d595d
Extend lifetime deadline for OIDC provider
kevinoconnor7 Feb 13, 2019
c30c7c8
Add OIDC discovery URL environment var
kevinoconnor7 Feb 14, 2019
0dba59c
Allow OIDC as a provider in options
kevinoconnor7 Feb 14, 2019
a736235
OIDC doesn't require a token validation endpoint (though extensions d…
kevinoconnor7 Feb 14, 2019
eecf0a8
Merge branch 'master' into azure-ad-provider
Jul 2, 2019
552ce5b
go fmt
Jul 2, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,22 @@ require (
github.com/18F/hmacauth v0.0.0-20151013130326-9232a6386b73
github.com/benbjohnson/clock v0.0.0-20161215174838-7dc76406b6d3
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
github.com/coreos/go-oidc v2.0.0+incompatible
github.com/datadog/datadog-go v0.0.0-20180822151419-281ae9f2d895
github.com/hashicorp/golang-lru v0.5.1
github.com/imdario/mergo v0.3.7
github.com/kelseyhightower/envconfig v1.3.0
github.com/mccutchen/go-httpbin v1.1.1
github.com/micro/go-micro v1.5.0
github.com/miscreant/miscreant-go v0.0.0-20181010193435-325cbd69228b
github.com/mitchellh/mapstructure v1.1.2
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
github.com/rakyll/statik v0.1.6
github.com/sirupsen/logrus v1.4.2
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
golang.org/x/sync v0.0.0-20190423024810-112230192c58
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522
google.golang.org/api v0.5.0
gopkg.in/square/go-jose.v2 v2.3.1
gopkg.in/yaml.v2 v2.2.2
)
7 changes: 7 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/containerd/continuity v0.0.0-20181203112020-004b46473808/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-oidc v2.0.0+incompatible h1:+RStIopZ8wooMx+Vs5Bt8zMXxV1ABl5LbakNExNmZIg=
github.com/coreos/go-oidc v2.0.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
github.com/datadog/datadog-go v0.0.0-20180822151419-281ae9f2d895 h1:VTq58gB0MvQpLAz2kfeSBchIAi9+zGRMTh+pyfXEoGs=
github.com/datadog/datadog-go v0.0.0-20180822151419-281ae9f2d895/go.mod h1:Mo2ZYXXA9Kp6qoXibOPpsSwkwZ67pcianic5+LKUZvY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down Expand Up @@ -218,6 +220,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/posener/complete v1.2.1/go.mod h1:6gapUrK/U1TAN7ciCoNRIdVC5sbdBTUh1DKN0g6uH7E=
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU=
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
Expand Down Expand Up @@ -275,6 +279,7 @@ golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5 h1:8dUaAV7K4uHsF56JQWkprecIQKdPHtR9jCHF5nB8uzc=
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
Expand Down Expand Up @@ -389,6 +394,8 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/go-playground/validator.v9 v9.29.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
gopkg.in/redis.v3 v3.6.4/go.mod h1:6XeGv/CrsUFDU9aVbUdNykN7k1zVmoeg83KC9RbQfiU=
gopkg.in/square/go-jose.v2 v2.3.1 h1:SK5KegNXmKmqE342YYN2qPHEnUYeoMiXXl1poUlI+o4=
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/src-d/go-billy.v4 v4.2.1/go.mod h1:tm33zBoOwxjYHZIE+OV8bxTWFMJLrconzFMd38aARFk=
gopkg.in/src-d/go-billy.v4 v4.3.0/go.mod h1:tm33zBoOwxjYHZIE+OV8bxTWFMJLrconzFMd38aARFk=
gopkg.in/src-d/go-git-fixtures.v3 v3.1.1/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g=
Expand Down
10 changes: 5 additions & 5 deletions internal/auth/authenticator.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func (p *Authenticator) newMux() http.Handler {
serviceMux.HandleFunc("/start", p.withMethods(p.OAuthStart, "GET"))
serviceMux.HandleFunc("/sign_in", p.withMethods(p.validateClientID(p.validateRedirectURI(p.validateSignature(p.SignIn))), "GET"))
serviceMux.HandleFunc("/sign_out", p.withMethods(p.validateRedirectURI(p.validateSignature(p.SignOut)), "GET", "POST"))
serviceMux.HandleFunc("/callback", p.withMethods(p.OAuthCallback, "GET"))
serviceMux.HandleFunc("/callback", p.withMethods(p.OAuthCallback, "GET", "POST"))
serviceMux.HandleFunc("/profile", p.withMethods(p.validateClientID(p.validateClientSecret(p.GetProfile)), "GET"))
serviceMux.HandleFunc("/validate", p.withMethods(p.validateClientID(p.validateClientSecret(p.ValidateToken)), "GET"))
serviceMux.HandleFunc("/redeem", p.withMethods(p.validateClientID(p.validateClientSecret(p.Redeem)), "POST"))
Expand Down Expand Up @@ -460,8 +460,8 @@ func (p *Authenticator) OAuthStart(rw http.ResponseWriter, req *http.Request) {
// Here we validate the redirect that is nested within the redirect_uri.
// `authRedirectURL` points to step D, `proxyRedirectURL` points to step E.
//
// A* B C D E
// /start -> Google -> auth /callback -> /sign_in -> proxy /callback
// A* B C D E
// /start -> IdProvider -> auth /callback -> /sign_in -> proxy /callback
//
// * you are here
proxyRedirectURL, err := url.Parse(authRedirectURL.Query().Get("redirect_uri"))
Expand All @@ -485,7 +485,7 @@ func (p *Authenticator) OAuthStart(rw http.ResponseWriter, req *http.Request) {

func (p *Authenticator) redeemCode(host, code string) (*sessions.SessionState, error) {
// The authenticator redeems `code` for an access token, and uses the token to request user
// info from the provider (Google).
// info from the provider.

redirectURI := p.GetRedirectURI(host)
// see providers/google.go#Redeem for more info
Expand All @@ -501,7 +501,7 @@ func (p *Authenticator) redeemCode(host, code string) (*sessions.SessionState, e
}

func (p *Authenticator) getOAuthCallback(rw http.ResponseWriter, req *http.Request) (string, error) {
// After the provider (Google) redirects back to the sso proxy, the proxy uses this
// After the provider redirects back to the sso proxy, the proxy uses this
// endpoint to set up auth cookies.
logger := log.NewLogEntry()

Expand Down
30 changes: 30 additions & 0 deletions internal/auth/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,9 @@ type ProviderConfig struct {
Scope string `mapstructure:"scope"`

// provider specific
AzureProviderConfig AzureProviderConfig `mapstructure:"azure"`
sporkmonger marked this conversation as resolved.
Show resolved Hide resolved
GoogleProviderConfig GoogleProviderConfig `mapstructure:"google"`
OIDCProviderConfig OIDCProviderConfig `mapstructure:"oidc"`
OktaProviderConfig OktaProviderConfig `mapstructure:"okta"`

// caching
Expand Down Expand Up @@ -225,6 +227,22 @@ func (pc ProviderConfig) Validate() error {
return nil
}

type AzureProviderConfig struct {
Tenant string `mapstructure:"tenant"`
ApprovalPrompt string `mapstructure:"prompt"`
}

func (apc AzureProviderConfig) Validate() error {
if apc.Tenant == "" {
return xerrors.New("must specify tenant ID")
}

if apc.ApprovalPrompt == "" {
apc.ApprovalPrompt = "consent"
}
return nil
}

type GoogleProviderConfig struct {
Credentials string `mapstructure:"credentials"`
Impersonate string `mapstructure:"impersonate"`
Expand All @@ -250,6 +268,18 @@ func (gpc GoogleProviderConfig) Validate() error {
return nil
}

type OIDCProviderConfig struct {
DiscoveryURL string `mapstructure:"discovery"`
}

func (opc OIDCProviderConfig) Validate() error {
if opc.DiscoveryURL == "" {
return xerrors.New("must specify discovery URL")
}

return nil
}

type OktaProviderConfig struct {
ServerID string `mapstructure:"server"`
OrgURL string `mapstructure:"url"`
Expand Down
17 changes: 16 additions & 1 deletion internal/auth/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,15 @@ func newProvider(pc ProviderConfig, sc SessionConfig) (providers.Provider, error

var singleFlightProvider providers.Provider
switch pc.ProviderType {
case providers.GoogleProviderName: // Google
case providers.AzureProviderName:
apc := pc.AzureProviderConfig
azureProvider, err := providers.NewAzureV2Provider(p)
if err != nil {
return nil, err
}
azureProvider.Configure(apc.Tenant)
singleFlightProvider = providers.NewSingleFlightProvider(azureProvider)
case providers.GoogleProviderName:
gpc := pc.GoogleProviderConfig
googleProvider, err := providers.NewGoogleProvider(p,
gpc.ApprovalPrompt,
Expand All @@ -41,6 +49,13 @@ func newProvider(pc ProviderConfig, sc SessionConfig) (providers.Provider, error
googleProvider.GroupsCache = cache

singleFlightProvider = providers.NewSingleFlightProvider(googleProvider)
case providers.OIDCProviderName:
opc := pc.OIDCProviderConfig
oidcProvider, err := providers.NewOIDCProvider(p, opc.DiscoveryURL)
if err != nil {
return nil, err
}
singleFlightProvider = providers.NewSingleFlightProvider(oidcProvider)
case providers.OktaProviderName:
opc := pc.OktaProviderConfig
oktaProvider, err := providers.NewOktaProvider(p, opc.OrgURL, opc.ServerID)
Expand Down