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
fd53c0a3
Unverified
Commit
fd53c0a3
authored
Jul 25, 2019
by
Stephan Renatus
Committed by
GitHub
Jul 25, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1496 from srenatus/sr/add-connector-id-to-example-app
add connector_id to example app
parents
20a858da
8561a663
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
60 additions
and
40 deletions
+60
-40
main.go
cmd/example-app/main.go
+17
-4
templates.go
cmd/example-app/templates.go
+7
-4
handlers.go
server/handlers.go
+17
-13
oauth2.go
server/oauth2.go
+19
-19
No files found.
cmd/example-app/main.go
View file @
fd53c0a3
...
@@ -237,6 +237,10 @@ func (a *app) handleLogin(w http.ResponseWriter, r *http.Request) {
...
@@ -237,6 +237,10 @@ func (a *app) handleLogin(w http.ResponseWriter, r *http.Request) {
for
_
,
client
:=
range
clients
{
for
_
,
client
:=
range
clients
{
scopes
=
append
(
scopes
,
"audience:server:client_id:"
+
client
)
scopes
=
append
(
scopes
,
"audience:server:client_id:"
+
client
)
}
}
connectorID
:=
""
if
id
:=
r
.
FormValue
(
"connector_id"
);
id
!=
""
{
connectorID
=
id
}
authCodeURL
:=
""
authCodeURL
:=
""
scopes
=
append
(
scopes
,
"openid"
,
"profile"
,
"email"
)
scopes
=
append
(
scopes
,
"openid"
,
"profile"
,
"email"
)
...
@@ -248,6 +252,9 @@ func (a *app) handleLogin(w http.ResponseWriter, r *http.Request) {
...
@@ -248,6 +252,9 @@ func (a *app) handleLogin(w http.ResponseWriter, r *http.Request) {
}
else
{
}
else
{
authCodeURL
=
a
.
oauth2Config
(
scopes
)
.
AuthCodeURL
(
exampleAppState
,
oauth2
.
AccessTypeOffline
)
authCodeURL
=
a
.
oauth2Config
(
scopes
)
.
AuthCodeURL
(
exampleAppState
,
oauth2
.
AccessTypeOffline
)
}
}
if
connectorID
!=
""
{
authCodeURL
=
authCodeURL
+
"&connector_id="
+
connectorID
}
http
.
Redirect
(
w
,
r
,
authCodeURL
,
http
.
StatusSeeOther
)
http
.
Redirect
(
w
,
r
,
authCodeURL
,
http
.
StatusSeeOther
)
}
}
...
@@ -307,7 +314,7 @@ func (a *app) handleCallback(w http.ResponseWriter, r *http.Request) {
...
@@ -307,7 +314,7 @@ func (a *app) handleCallback(w http.ResponseWriter, r *http.Request) {
idToken
,
err
:=
a
.
verifier
.
Verify
(
r
.
Context
(),
rawIDToken
)
idToken
,
err
:=
a
.
verifier
.
Verify
(
r
.
Context
(),
rawIDToken
)
if
err
!=
nil
{
if
err
!=
nil
{
http
.
Error
(
w
,
fmt
.
Sprintf
(
"
F
ailed to verify ID token: %v"
,
err
),
http
.
StatusInternalServerError
)
http
.
Error
(
w
,
fmt
.
Sprintf
(
"
f
ailed to verify ID token: %v"
,
err
),
http
.
StatusInternalServerError
)
return
return
}
}
...
@@ -318,10 +325,16 @@ func (a *app) handleCallback(w http.ResponseWriter, r *http.Request) {
...
@@ -318,10 +325,16 @@ func (a *app) handleCallback(w http.ResponseWriter, r *http.Request) {
}
}
var
claims
json
.
RawMessage
var
claims
json
.
RawMessage
idToken
.
Claims
(
&
claims
)
if
err
:=
idToken
.
Claims
(
&
claims
);
err
!=
nil
{
http
.
Error
(
w
,
fmt
.
Sprintf
(
"error decoding ID token claims: %v"
,
err
),
http
.
StatusInternalServerError
)
return
}
buff
:=
new
(
bytes
.
Buffer
)
buff
:=
new
(
bytes
.
Buffer
)
json
.
Indent
(
buff
,
[]
byte
(
claims
),
""
,
" "
)
if
err
:=
json
.
Indent
(
buff
,
[]
byte
(
claims
),
""
,
" "
);
err
!=
nil
{
http
.
Error
(
w
,
fmt
.
Sprintf
(
"error indenting ID token claims: %v"
,
err
),
http
.
StatusInternalServerError
)
return
}
renderToken
(
w
,
a
.
redirectURI
,
rawIDToken
,
accessToken
,
token
.
RefreshToken
,
buff
.
Bytes
())
renderToken
(
w
,
a
.
redirectURI
,
rawIDToken
,
accessToken
,
token
.
RefreshToken
,
buff
.
String
())
}
}
cmd/example-app/templates.go
View file @
fd53c0a3
...
@@ -15,8 +15,11 @@ var indexTmpl = template.Must(template.New("index.html").Parse(`<html>
...
@@ -15,8 +15,11 @@ var indexTmpl = template.Must(template.New("index.html").Parse(`<html>
<p>
<p>
Extra scopes:<input type="text" name="extra_scopes" placeholder="list of scopes">
Extra scopes:<input type="text" name="extra_scopes" placeholder="list of scopes">
</p>
</p>
<p>
<p>
Request offline access:<input type="checkbox" name="offline_access" value="yes" checked>
Connector ID:<input type="text" name="connector_id" placeholder="connector id">
</p>
<p>
Request offline access:<input type="checkbox" name="offline_access" value="yes" checked>
</p>
</p>
<input type="submit" value="Login">
<input type="submit" value="Login">
</form>
</form>
...
@@ -63,13 +66,13 @@ pre {
...
@@ -63,13 +66,13 @@ pre {
</html>
</html>
`
))
`
))
func
renderToken
(
w
http
.
ResponseWriter
,
redirectURL
,
idToken
,
accessToken
,
refreshToken
string
,
claims
[]
byte
)
{
func
renderToken
(
w
http
.
ResponseWriter
,
redirectURL
,
idToken
,
accessToken
,
refreshToken
,
claims
string
)
{
renderTemplate
(
w
,
tokenTmpl
,
tokenTmplData
{
renderTemplate
(
w
,
tokenTmpl
,
tokenTmplData
{
IDToken
:
idToken
,
IDToken
:
idToken
,
AccessToken
:
accessToken
,
AccessToken
:
accessToken
,
RefreshToken
:
refreshToken
,
RefreshToken
:
refreshToken
,
RedirectURL
:
redirectURL
,
RedirectURL
:
redirectURL
,
Claims
:
string
(
claims
)
,
Claims
:
claims
,
})
})
}
}
...
...
server/handlers.go
View file @
fd53c0a3
...
@@ -200,17 +200,21 @@ func (s *Server) handleAuthorization(w http.ResponseWriter, r *http.Request) {
...
@@ -200,17 +200,21 @@ func (s *Server) handleAuthorization(w http.ResponseWriter, r *http.Request) {
authReq
,
err
:=
s
.
parseAuthorizationRequest
(
r
)
authReq
,
err
:=
s
.
parseAuthorizationRequest
(
r
)
if
err
!=
nil
{
if
err
!=
nil
{
s
.
logger
.
Errorf
(
"Failed to parse authorization request: %v"
,
err
)
s
.
logger
.
Errorf
(
"Failed to parse authorization request: %v"
,
err
)
if
handler
,
ok
:=
err
.
Handle
();
ok
{
status
:=
http
.
StatusInternalServerError
// client_id and redirect_uri checked out and we can redirect back to
// the client with the error.
// If this is an authErr, let's let it handle the error, or update the HTTP
handler
.
ServeHTTP
(
w
,
r
)
// status code
return
if
err
,
ok
:=
err
.
(
*
authErr
);
ok
{
if
handler
,
ok
:=
err
.
Handle
();
ok
{
// client_id and redirect_uri checked out and we can redirect back to
// the client with the error.
handler
.
ServeHTTP
(
w
,
r
)
return
}
status
=
err
.
Status
()
}
}
// Otherwise render the error to the user.
s
.
renderError
(
w
,
status
,
err
.
Error
())
//
// TODO(ericchiang): Should we just always render the error?
s
.
renderError
(
w
,
err
.
Status
(),
err
.
Error
())
return
return
}
}
...
@@ -220,15 +224,15 @@ func (s *Server) handleAuthorization(w http.ResponseWriter, r *http.Request) {
...
@@ -220,15 +224,15 @@ func (s *Server) handleAuthorization(w http.ResponseWriter, r *http.Request) {
//
//
// See: https://github.com/dexidp/dex/issues/646
// See: https://github.com/dexidp/dex/issues/646
authReq
.
Expiry
=
s
.
now
()
.
Add
(
s
.
authRequestsValidFor
)
authReq
.
Expiry
=
s
.
now
()
.
Add
(
s
.
authRequestsValidFor
)
if
err
:=
s
.
storage
.
CreateAuthRequest
(
authReq
);
err
!=
nil
{
if
err
:=
s
.
storage
.
CreateAuthRequest
(
*
authReq
);
err
!=
nil
{
s
.
logger
.
Errorf
(
"Failed to create authorization request: %v"
,
err
)
s
.
logger
.
Errorf
(
"Failed to create authorization request: %v"
,
err
)
s
.
renderError
(
w
,
http
.
StatusInternalServerError
,
"Failed to connect to the database."
)
s
.
renderError
(
w
,
http
.
StatusInternalServerError
,
"Failed to connect to the database."
)
return
return
}
}
connectors
,
e
:=
s
.
storage
.
ListConnectors
()
connectors
,
e
rr
:=
s
.
storage
.
ListConnectors
()
if
e
!=
nil
{
if
e
rr
!=
nil
{
s
.
logger
.
Errorf
(
"Failed to get list of connectors: %v"
,
e
)
s
.
logger
.
Errorf
(
"Failed to get list of connectors: %v"
,
e
rr
)
s
.
renderError
(
w
,
http
.
StatusInternalServerError
,
"Failed to retrieve connector list."
)
s
.
renderError
(
w
,
http
.
StatusInternalServerError
,
"Failed to retrieve connector list."
)
return
return
}
}
...
...
server/oauth2.go
View file @
fd53c0a3
...
@@ -379,14 +379,14 @@ func (s *Server) newIDToken(clientID string, claims storage.Claims, scopes []str
...
@@ -379,14 +379,14 @@ func (s *Server) newIDToken(clientID string, claims storage.Claims, scopes []str
}
}
// parse the initial request from the OAuth2 client.
// parse the initial request from the OAuth2 client.
func
(
s
*
Server
)
parseAuthorizationRequest
(
r
*
http
.
Request
)
(
req
storage
.
AuthRequest
,
oauth2Err
*
authEr
r
)
{
func
(
s
*
Server
)
parseAuthorizationRequest
(
r
*
http
.
Request
)
(
*
storage
.
AuthRequest
,
erro
r
)
{
if
err
:=
r
.
ParseForm
();
err
!=
nil
{
if
err
:=
r
.
ParseForm
();
err
!=
nil
{
return
req
,
&
authErr
{
""
,
""
,
errInvalidRequest
,
"Failed to parse request body."
}
return
nil
,
&
authErr
{
""
,
""
,
errInvalidRequest
,
"Failed to parse request body."
}
}
}
q
:=
r
.
Form
q
:=
r
.
Form
redirectURI
,
err
:=
url
.
QueryUnescape
(
q
.
Get
(
"redirect_uri"
))
redirectURI
,
err
:=
url
.
QueryUnescape
(
q
.
Get
(
"redirect_uri"
))
if
err
!=
nil
{
if
err
!=
nil
{
return
req
,
&
authErr
{
""
,
""
,
errInvalidRequest
,
"No redirect_uri provided."
}
return
nil
,
&
authErr
{
""
,
""
,
errInvalidRequest
,
"No redirect_uri provided."
}
}
}
clientID
:=
q
.
Get
(
"client_id"
)
clientID
:=
q
.
Get
(
"client_id"
)
...
@@ -401,25 +401,25 @@ func (s *Server) parseAuthorizationRequest(r *http.Request) (req storage.AuthReq
...
@@ -401,25 +401,25 @@ func (s *Server) parseAuthorizationRequest(r *http.Request) (req storage.AuthReq
if
err
!=
nil
{
if
err
!=
nil
{
if
err
==
storage
.
ErrNotFound
{
if
err
==
storage
.
ErrNotFound
{
description
:=
fmt
.
Sprintf
(
"Invalid client_id (%q)."
,
clientID
)
description
:=
fmt
.
Sprintf
(
"Invalid client_id (%q)."
,
clientID
)
return
req
,
&
authErr
{
""
,
""
,
errUnauthorizedClient
,
description
}
return
nil
,
&
authErr
{
""
,
""
,
errUnauthorizedClient
,
description
}
}
}
s
.
logger
.
Errorf
(
"Failed to get client: %v"
,
err
)
s
.
logger
.
Errorf
(
"Failed to get client: %v"
,
err
)
return
req
,
&
authErr
{
""
,
""
,
errServerError
,
""
}
return
nil
,
&
authErr
{
""
,
""
,
errServerError
,
""
}
}
}
if
connectorID
!=
""
{
if
connectorID
!=
""
{
connectors
,
err
:=
s
.
storage
.
ListConnectors
()
connectors
,
err
:=
s
.
storage
.
ListConnectors
()
if
err
!=
nil
{
if
err
!=
nil
{
return
req
,
&
authErr
{
""
,
""
,
errServerError
,
"Unable to retrieve connectors"
}
return
nil
,
&
authErr
{
""
,
""
,
errServerError
,
"Unable to retrieve connectors"
}
}
}
if
!
validateConnectorID
(
connectors
,
connectorID
)
{
if
!
validateConnectorID
(
connectors
,
connectorID
)
{
return
req
,
&
authErr
{
""
,
""
,
errInvalidRequest
,
"Invalid ConnectorID"
}
return
nil
,
&
authErr
{
""
,
""
,
errInvalidRequest
,
"Invalid ConnectorID"
}
}
}
}
}
if
!
validateRedirectURI
(
client
,
redirectURI
)
{
if
!
validateRedirectURI
(
client
,
redirectURI
)
{
description
:=
fmt
.
Sprintf
(
"Unregistered redirect_uri (%q)."
,
redirectURI
)
description
:=
fmt
.
Sprintf
(
"Unregistered redirect_uri (%q)."
,
redirectURI
)
return
req
,
&
authErr
{
""
,
""
,
errInvalidRequest
,
description
}
return
nil
,
&
authErr
{
""
,
""
,
errInvalidRequest
,
description
}
}
}
// From here on out, we want to redirect back to the client with an error.
// From here on out, we want to redirect back to the client with an error.
...
@@ -446,7 +446,7 @@ func (s *Server) parseAuthorizationRequest(r *http.Request) (req storage.AuthReq
...
@@ -446,7 +446,7 @@ func (s *Server) parseAuthorizationRequest(r *http.Request) (req storage.AuthReq
isTrusted
,
err
:=
s
.
validateCrossClientTrust
(
clientID
,
peerID
)
isTrusted
,
err
:=
s
.
validateCrossClientTrust
(
clientID
,
peerID
)
if
err
!=
nil
{
if
err
!=
nil
{
return
req
,
newErr
(
errServerError
,
"Internal server error."
)
return
nil
,
newErr
(
errServerError
,
"Internal server error."
)
}
}
if
!
isTrusted
{
if
!
isTrusted
{
invalidScopes
=
append
(
invalidScopes
,
scope
)
invalidScopes
=
append
(
invalidScopes
,
scope
)
...
@@ -454,13 +454,13 @@ func (s *Server) parseAuthorizationRequest(r *http.Request) (req storage.AuthReq
...
@@ -454,13 +454,13 @@ func (s *Server) parseAuthorizationRequest(r *http.Request) (req storage.AuthReq
}
}
}
}
if
!
hasOpenIDScope
{
if
!
hasOpenIDScope
{
return
req
,
newErr
(
"invalid_scope"
,
`Missing required scope(s) ["openid"].`
)
return
nil
,
newErr
(
"invalid_scope"
,
`Missing required scope(s) ["openid"].`
)
}
}
if
len
(
unrecognized
)
>
0
{
if
len
(
unrecognized
)
>
0
{
return
req
,
newErr
(
"invalid_scope"
,
"Unrecognized scope(s) %q"
,
unrecognized
)
return
nil
,
newErr
(
"invalid_scope"
,
"Unrecognized scope(s) %q"
,
unrecognized
)
}
}
if
len
(
invalidScopes
)
>
0
{
if
len
(
invalidScopes
)
>
0
{
return
req
,
newErr
(
"invalid_scope"
,
"Client can't request scope(s) %q"
,
invalidScopes
)
return
nil
,
newErr
(
"invalid_scope"
,
"Client can't request scope(s) %q"
,
invalidScopes
)
}
}
var
rt
struct
{
var
rt
struct
{
...
@@ -478,23 +478,23 @@ func (s *Server) parseAuthorizationRequest(r *http.Request) (req storage.AuthReq
...
@@ -478,23 +478,23 @@ func (s *Server) parseAuthorizationRequest(r *http.Request) (req storage.AuthReq
case
responseTypeToken
:
case
responseTypeToken
:
rt
.
token
=
true
rt
.
token
=
true
default
:
default
:
return
req
,
newErr
(
"invalid_request"
,
"Invalid response type %q"
,
responseType
)
return
nil
,
newErr
(
"invalid_request"
,
"Invalid response type %q"
,
responseType
)
}
}
if
!
s
.
supportedResponseTypes
[
responseType
]
{
if
!
s
.
supportedResponseTypes
[
responseType
]
{
return
req
,
newErr
(
errUnsupportedResponseType
,
"Unsupported response type %q"
,
responseType
)
return
nil
,
newErr
(
errUnsupportedResponseType
,
"Unsupported response type %q"
,
responseType
)
}
}
}
}
if
len
(
responseTypes
)
==
0
{
if
len
(
responseTypes
)
==
0
{
return
req
,
newErr
(
"invalid_requests"
,
"No response_type provided"
)
return
nil
,
newErr
(
"invalid_requests"
,
"No response_type provided"
)
}
}
if
rt
.
token
&&
!
rt
.
code
&&
!
rt
.
idToken
{
if
rt
.
token
&&
!
rt
.
code
&&
!
rt
.
idToken
{
// "token" can't be provided by its own.
// "token" can't be provided by its own.
//
//
// https://openid.net/specs/openid-connect-core-1_0.html#Authentication
// https://openid.net/specs/openid-connect-core-1_0.html#Authentication
return
req
,
newErr
(
"invalid_request"
,
"Response type 'token' must be provided with type 'id_token' and/or 'code'"
)
return
nil
,
newErr
(
"invalid_request"
,
"Response type 'token' must be provided with type 'id_token' and/or 'code'"
)
}
}
if
!
rt
.
code
{
if
!
rt
.
code
{
// Either "id_token code" or "id_token" has been provided which implies the
// Either "id_token code" or "id_token" has been provided which implies the
...
@@ -502,17 +502,17 @@ func (s *Server) parseAuthorizationRequest(r *http.Request) (req storage.AuthReq
...
@@ -502,17 +502,17 @@ func (s *Server) parseAuthorizationRequest(r *http.Request) (req storage.AuthReq
//
//
// https://openid.net/specs/openid-connect-core-1_0.html#ImplicitAuthRequest
// https://openid.net/specs/openid-connect-core-1_0.html#ImplicitAuthRequest
if
nonce
==
""
{
if
nonce
==
""
{
return
req
,
newErr
(
"invalid_request"
,
"Response type 'token' requires a 'nonce' value."
)
return
nil
,
newErr
(
"invalid_request"
,
"Response type 'token' requires a 'nonce' value."
)
}
}
}
}
if
rt
.
token
{
if
rt
.
token
{
if
redirectURI
==
redirectURIOOB
{
if
redirectURI
==
redirectURIOOB
{
err
:=
fmt
.
Sprintf
(
"Cannot use response type 'token' with redirect_uri '%s'."
,
redirectURIOOB
)
err
:=
fmt
.
Sprintf
(
"Cannot use response type 'token' with redirect_uri '%s'."
,
redirectURIOOB
)
return
req
,
newErr
(
"invalid_request"
,
err
)
return
nil
,
newErr
(
"invalid_request"
,
err
)
}
}
}
}
return
storage
.
AuthRequest
{
return
&
storage
.
AuthRequest
{
ID
:
storage
.
NewID
(),
ID
:
storage
.
NewID
(),
ClientID
:
client
.
ID
,
ClientID
:
client
.
ID
,
State
:
state
,
State
:
state
,
...
...
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