Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
D
dex
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
dex
Commits
bef9f3c2
Commit
bef9f3c2
authored
Aug 11, 2016
by
Eric Chiang
Committed by
GitHub
Aug 11, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #542 from whitlockjc/uaa-connector
connector: add uaa connector
parents
ac518139
27b80cbc
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
241 additions
and
0 deletions
+241
-0
connectors-configuration.md
Documentation/connectors-configuration.md
+35
-0
connector_uaa.go
connector/connector_uaa.go
+158
-0
connector_uaa_test.go
connector/connector_uaa_test.go
+47
-0
http.go
server/http.go
+1
-0
No files found.
Documentation/connectors-configuration.md
View file @
bef9f3c2
...
@@ -237,3 +237,38 @@ To set a connectors configuration in dex, put it in some temporary file, then us
...
@@ -237,3 +237,38 @@ To set a connectors configuration in dex, put it in some temporary file, then us
```
```
dexctl --db-url=$DEX_DB_URL set-connector-configs /tmp/dex_connectors.json
dexctl --db-url=$DEX_DB_URL set-connector-configs /tmp/dex_connectors.json
```
```
### `uaa` connector
This connector config lets users authenticate through the
[
CloudFoundry User Account and Authentication (UAA) Server
](
https://github.com/cloudfoundry/uaa
)
. In addition to
`id`
and
`type`
, the
`uaa`
connector takes the following additional fields:
*
clientID: a
`string`
. The UAA OAuth application client ID.
*
clientSecret: a
`string`
. The UAA OAuth application client secret.
*
serverURL: a
`string`
. The full URL to the UAA service.
To begin, register an OAuth application with UAA. To register dex as a client of your UAA application, there are two
things your OAuth application needs to have configured properly:
*
Make sure dex's redirect URL _(
`ISSUER_URL/auth/$CONNECTOR_ID/callback`
)_ is in the application's
`redirect_uri`
list
*
Make sure the
`openid`
scope is in the application's
`scope`
list
Regarding the
`redirect_uri`
list, as an example if you were running dex at
`https://auth.example.com/bar`
, the UAA
OAuth application's
`redirect_uri`
list would need to contain
`https://auth.example.com/bar/auth/uaa/callback`
.
Here's an example of a
`uaa`
connector _(The
`clientID`
and
`clientSecret`
should be replaced by values provided to UAA
and the
`serverURL`
should be the fully-qualified URL to your UAA server)_:
```
{
"type": "uaa",
"id": "example-uaa",
"clientID": "$UAA_OAUTH_APPLICATION_CLIENT_ID",
"clientSecret": "$UAA_OAUTH_APPLICATION_CLIENT_SECRET",
"serverURL": "$UAA_SERVER_URL"
}
```
The
`uaa`
connector requests only the
`openid`
scope which allows dex the ability to query the user's identity
information.
connector/connector_uaa.go
0 → 100644
View file @
bef9f3c2
package
connector
import
(
"encoding/json"
"fmt"
"html/template"
"net/http"
"net/url"
"path"
chttp
"github.com/coreos/go-oidc/http"
"github.com/coreos/go-oidc/oauth2"
"github.com/coreos/go-oidc/oidc"
)
const
(
UAAConnectorType
=
"uaa"
)
type
UAAConnectorConfig
struct
{
ID
string
`json:"id"`
ClientID
string
`json:"clientID"`
ClientSecret
string
`json:"clientSecret"`
ServerURL
string
`json:"serverURL"`
}
// standard error form returned by UAA
type
uaaError
struct
{
ErrorDescription
string
`json:"error_description"`
ErrorType
string
`json:"error"`
}
type
uaaOAuth2Connector
struct
{
clientID
string
clientSecret
string
client
*
oauth2
.
Client
uaaBaseURL
*
url
.
URL
}
func
init
()
{
RegisterConnectorConfigType
(
UAAConnectorType
,
func
()
ConnectorConfig
{
return
&
UAAConnectorConfig
{}
})
}
func
(
cfg
*
UAAConnectorConfig
)
ConnectorID
()
string
{
return
cfg
.
ID
}
func
(
cfg
*
UAAConnectorConfig
)
ConnectorType
()
string
{
return
UAAConnectorType
}
func
(
cfg
*
UAAConnectorConfig
)
Connector
(
ns
url
.
URL
,
lf
oidc
.
LoginFunc
,
tpls
*
template
.
Template
)
(
Connector
,
error
)
{
uaaBaseURL
,
err
:=
url
.
ParseRequestURI
(
cfg
.
ServerURL
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"Invalid configuration. UAA URL is invalid: %v"
,
err
)
}
if
!
uaaBaseURL
.
IsAbs
()
{
return
nil
,
fmt
.
Errorf
(
"Invalid configuration. UAA URL must be absolute"
)
}
ns
.
Path
=
path
.
Join
(
ns
.
Path
,
httpPathCallback
)
oauth2Conn
,
err
:=
newUAAConnector
(
cfg
,
uaaBaseURL
,
ns
.
String
())
if
err
!=
nil
{
return
nil
,
err
}
return
&
OAuth2Connector
{
id
:
cfg
.
ID
,
loginFunc
:
lf
,
cbURL
:
ns
,
conn
:
oauth2Conn
,
},
nil
}
func
(
err
uaaError
)
Error
()
string
{
return
fmt
.
Sprintf
(
"uaa (%s): %s"
,
err
.
ErrorType
,
err
.
ErrorDescription
)
}
func
(
c
*
uaaOAuth2Connector
)
Client
()
*
oauth2
.
Client
{
return
c
.
client
}
func
(
c
*
uaaOAuth2Connector
)
Healthy
()
error
{
return
nil
}
func
(
c
*
uaaOAuth2Connector
)
Identity
(
cli
chttp
.
Client
)
(
oidc
.
Identity
,
error
)
{
uaaUserInfoURL
:=
*
c
.
uaaBaseURL
uaaUserInfoURL
.
Path
=
path
.
Join
(
uaaUserInfoURL
.
Path
,
"/userinfo"
)
req
,
err
:=
http
.
NewRequest
(
"GET"
,
uaaUserInfoURL
.
String
(),
nil
)
if
err
!=
nil
{
return
oidc
.
Identity
{},
err
}
resp
,
err
:=
cli
.
Do
(
req
)
if
err
!=
nil
{
return
oidc
.
Identity
{},
fmt
.
Errorf
(
"get: %v"
,
err
)
}
defer
resp
.
Body
.
Close
()
switch
{
case
resp
.
StatusCode
>=
400
&&
resp
.
StatusCode
<
600
:
// attempt to decode error from UAA
var
authErr
uaaError
if
err
:=
json
.
NewDecoder
(
resp
.
Body
)
.
Decode
(
&
authErr
);
err
!=
nil
{
return
oidc
.
Identity
{},
oauth2
.
NewError
(
oauth2
.
ErrorAccessDenied
)
}
return
oidc
.
Identity
{},
authErr
case
resp
.
StatusCode
==
http
.
StatusOK
:
default
:
return
oidc
.
Identity
{},
fmt
.
Errorf
(
"unexpected status from providor %s"
,
resp
.
Status
)
}
var
user
struct
{
UserID
string
`json:"user_id"`
Email
string
`json:"email"`
Name
string
`json:"name"`
UserName
string
`json:"user_name"`
}
if
err
:=
json
.
NewDecoder
(
resp
.
Body
)
.
Decode
(
&
user
);
err
!=
nil
{
return
oidc
.
Identity
{},
fmt
.
Errorf
(
"getting user info: %v"
,
err
)
}
name
:=
user
.
Name
if
name
==
""
{
name
=
user
.
UserName
}
return
oidc
.
Identity
{
ID
:
user
.
UserID
,
Name
:
name
,
Email
:
user
.
Email
,
},
nil
}
func
(
c
*
uaaOAuth2Connector
)
TrustedEmailProvider
()
bool
{
return
false
}
func
newUAAConnector
(
cfg
*
UAAConnectorConfig
,
uaaBaseURL
*
url
.
URL
,
cbURL
string
)
(
oauth2Connector
,
error
)
{
uaaAuthURL
:=
*
uaaBaseURL
uaaTokenURL
:=
*
uaaBaseURL
uaaAuthURL
.
Path
=
path
.
Join
(
uaaAuthURL
.
Path
,
"/oauth/authorize"
)
uaaTokenURL
.
Path
=
path
.
Join
(
uaaTokenURL
.
Path
,
"/oauth/token"
)
config
:=
oauth2
.
Config
{
Credentials
:
oauth2
.
ClientCredentials
{
ID
:
cfg
.
ClientID
,
Secret
:
cfg
.
ClientSecret
},
AuthURL
:
uaaAuthURL
.
String
(),
TokenURL
:
uaaTokenURL
.
String
(),
Scope
:
[]
string
{
"openid"
},
AuthMethod
:
oauth2
.
AuthMethodClientSecretPost
,
RedirectURL
:
cbURL
,
}
cli
,
err
:=
oauth2
.
NewClient
(
http
.
DefaultClient
,
config
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
uaaOAuth2Connector
{
clientID
:
cfg
.
ClientID
,
clientSecret
:
cfg
.
ClientSecret
,
client
:
cli
,
uaaBaseURL
:
uaaBaseURL
,
},
nil
}
connector/connector_uaa_test.go
0 → 100644
View file @
bef9f3c2
package
connector
import
(
"testing"
)
func
TestUAAConnectorConfigInvalidserverURLNotAValidURL
(
t
*
testing
.
T
)
{
cc
:=
UAAConnectorConfig
{
ID
:
"uaa"
,
ClientID
:
"test-client"
,
ClientSecret
:
"test-client-secret"
,
ServerURL
:
"https//login.apigee.com"
,
}
_
,
err
:=
cc
.
Connector
(
ns
,
lf
,
templates
)
if
err
==
nil
{
t
.
Fatal
(
"Expected UAAConnector initialization to fail when UAA URL is an invalid URL"
)
}
}
func
TestUAAConnectorConfigInvalidserverURLNotAbsolute
(
t
*
testing
.
T
)
{
cc
:=
UAAConnectorConfig
{
ID
:
"uaa"
,
ClientID
:
"test-client"
,
ClientSecret
:
"test-client-secret"
,
ServerURL
:
"/uaa"
,
}
_
,
err
:=
cc
.
Connector
(
ns
,
lf
,
templates
)
if
err
==
nil
{
t
.
Fatal
(
"Expected UAAConnector initialization to fail when UAA URL is not an aboslute URL"
)
}
}
func
TestUAAConnectorConfigValidserverURL
(
t
*
testing
.
T
)
{
cc
:=
UAAConnectorConfig
{
ID
:
"uaa"
,
ClientID
:
"test-client"
,
ClientSecret
:
"test-client-secret"
,
ServerURL
:
"https://login.apigee.com"
,
}
_
,
err
:=
cc
.
Connector
(
ns
,
lf
,
templates
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
}
server/http.go
View file @
bef9f3c2
...
@@ -131,6 +131,7 @@ var connectorDisplayNameMap = map[string]string{
...
@@ -131,6 +131,7 @@ var connectorDisplayNameMap = map[string]string{
"local"
:
"Email"
,
"local"
:
"Email"
,
"github"
:
"GitHub"
,
"github"
:
"GitHub"
,
"bitbucket"
:
"Bitbucket"
,
"bitbucket"
:
"Bitbucket"
,
"uaa"
:
"CloudFoundry User Account and Authentication (UAA)"
,
}
}
type
Template
interface
{
type
Template
interface
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment