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
fe93f60a
Commit
fe93f60a
authored
Jan 17, 2017
by
rithu leena john
Committed by
GitHub
Jan 17, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #775 from xeonx/master
Allow CORS on keys and token endpoints
parents
ca7d2b8f
415a68f9
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
43 additions
and
106 deletions
+43
-106
config.go
cmd/dex/config.go
+5
-5
serve.go
cmd/dex/serve.go
+12
-12
handlers.go
server/handlers.go
+3
-11
handlers_test.go
server/handlers_test.go
+0
-58
server.go
server/server.go
+23
-20
No files found.
cmd/dex/config.go
View file @
fe93f60a
...
...
@@ -99,11 +99,11 @@ type OAuth2 struct {
// Web is the config format for the HTTP server.
type
Web
struct
{
HTTP
string
`json:"http"`
HTTPS
string
`json:"https"`
TLSCert
string
`json:"tlsCert"`
TLSKey
string
`json:"tlsKey"`
DiscoveryAllowedOrigins
[]
string
`json:"discoveryA
llowedOrigins"`
HTTP
string
`json:"http"`
HTTPS
string
`json:"https"`
TLSCert
string
`json:"tlsCert"`
TLSKey
string
`json:"tlsKey"`
AllowedOrigins
[]
string
`json:"a
llowedOrigins"`
}
// GRPC is the config for the gRPC API.
...
...
cmd/dex/serve.go
View file @
fe93f60a
...
...
@@ -179,24 +179,24 @@ func serve(cmd *cobra.Command, args []string) error {
if
c
.
OAuth2
.
SkipApprovalScreen
{
logger
.
Infof
(
"config skipping approval screen"
)
}
if
len
(
c
.
Web
.
Discovery
AllowedOrigins
)
>
0
{
logger
.
Infof
(
"config
discovery allowed origins: %s"
,
c
.
Web
.
Discovery
AllowedOrigins
)
if
len
(
c
.
Web
.
AllowedOrigins
)
>
0
{
logger
.
Infof
(
"config
allowed origins: %s"
,
c
.
Web
.
AllowedOrigins
)
}
// explicitly convert to UTC.
now
:=
func
()
time
.
Time
{
return
time
.
Now
()
.
UTC
()
}
serverConfig
:=
server
.
Config
{
SupportedResponseTypes
:
c
.
OAuth2
.
ResponseTypes
,
SkipApprovalScreen
:
c
.
OAuth2
.
SkipApprovalScreen
,
DiscoveryAllowedOrigins
:
c
.
Web
.
Discovery
AllowedOrigins
,
Issuer
:
c
.
Issuer
,
Connectors
:
connectors
,
Storage
:
s
,
Web
:
c
.
Frontend
,
EnablePasswordDB
:
c
.
EnablePasswordDB
,
Logger
:
logger
,
Now
:
now
,
SupportedResponseTypes
:
c
.
OAuth2
.
ResponseTypes
,
SkipApprovalScreen
:
c
.
OAuth2
.
SkipApprovalScreen
,
AllowedOrigins
:
c
.
Web
.
AllowedOrigins
,
Issuer
:
c
.
Issuer
,
Connectors
:
connectors
,
Storage
:
s
,
Web
:
c
.
Frontend
,
EnablePasswordDB
:
c
.
EnablePasswordDB
,
Logger
:
logger
,
Now
:
now
,
}
if
c
.
Expiry
.
SigningKeys
!=
""
{
signingKeys
,
err
:=
time
.
ParseDuration
(
c
.
Expiry
.
SigningKeys
)
...
...
server/handlers.go
View file @
fe93f60a
...
...
@@ -12,7 +12,6 @@ import (
"strings"
"time"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
jose
"gopkg.in/square/go-jose.v2"
...
...
@@ -104,7 +103,7 @@ type discovery struct {
Claims
[]
string
`json:"claims_supported"`
}
func
(
s
*
Server
)
discoveryHandler
()
(
http
.
Handler
,
error
)
{
func
(
s
*
Server
)
discoveryHandler
()
(
http
.
Handler
Func
,
error
)
{
d
:=
discovery
{
Issuer
:
s
.
issuerURL
.
String
(),
Auth
:
s
.
absURL
(
"/auth"
),
...
...
@@ -130,18 +129,11 @@ func (s *Server) discoveryHandler() (http.Handler, error) {
return
nil
,
fmt
.
Errorf
(
"failed to marshal discovery data: %v"
,
err
)
}
var
discoveryHandler
http
.
Handler
discoveryHandler
=
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
return
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
w
.
Header
()
.
Set
(
"Content-Type"
,
"application/json"
)
w
.
Header
()
.
Set
(
"Content-Length"
,
strconv
.
Itoa
(
len
(
data
)))
w
.
Write
(
data
)
})
if
len
(
s
.
discoveryAllowedOrigins
)
>
0
{
corsOption
:=
handlers
.
AllowedOrigins
(
s
.
discoveryAllowedOrigins
)
discoveryHandler
=
handlers
.
CORS
(
corsOption
)(
discoveryHandler
)
}
return
discoveryHandler
,
nil
}),
nil
}
// handleAuthorization handles the OAuth2 auth endpoint.
...
...
server/handlers_test.go
View file @
fe93f60a
...
...
@@ -22,61 +22,3 @@ func TestHandleHealth(t *testing.T) {
}
}
var
discoveryHandlerCORSTests
=
[]
struct
{
DiscoveryAllowedOrigins
[]
string
Origin
string
ResponseAllowOrigin
string
//The expected response: same as Origin in case of valid CORS flow
}{
{
nil
,
"http://foo.example"
,
""
},
//Default behavior: cross origin requests not allowed
{[]
string
{},
"http://foo.example"
,
""
},
{[]
string
{
"http://foo.example"
},
"http://foo.example"
,
"http://foo.example"
},
{[]
string
{
"http://bar.example"
,
"http://foo.example"
},
"http://foo.example"
,
"http://foo.example"
},
{[]
string
{
"*"
},
"http://foo.example"
,
"http://foo.example"
},
{[]
string
{
"http://bar.example"
},
"http://foo.example"
,
""
},
}
func
TestDiscoveryHandlerCORS
(
t
*
testing
.
T
)
{
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
Background
())
defer
cancel
()
for
_
,
testcase
:=
range
discoveryHandlerCORSTests
{
httpServer
,
server
:=
newTestServer
(
ctx
,
t
,
func
(
c
*
Config
)
{
c
.
DiscoveryAllowedOrigins
=
testcase
.
DiscoveryAllowedOrigins
})
defer
httpServer
.
Close
()
discoveryHandler
,
err
:=
server
.
discoveryHandler
()
if
err
!=
nil
{
t
.
Fatalf
(
"failed to get discovery handler: %v"
,
err
)
}
//Perform preflight request
rrPreflight
:=
httptest
.
NewRecorder
()
reqPreflight
:=
httptest
.
NewRequest
(
"OPTIONS"
,
"/.well-kown/openid-configuration"
,
nil
)
reqPreflight
.
Header
.
Set
(
"Origin"
,
testcase
.
Origin
)
reqPreflight
.
Header
.
Set
(
"Access-Control-Request-Method"
,
"GET"
)
discoveryHandler
.
ServeHTTP
(
rrPreflight
,
reqPreflight
)
if
rrPreflight
.
Code
!=
http
.
StatusOK
{
t
.
Errorf
(
"expected 200 got %d"
,
rrPreflight
.
Code
)
}
headerAccessControlPreflight
:=
rrPreflight
.
HeaderMap
.
Get
(
"Access-Control-Allow-Origin"
)
if
headerAccessControlPreflight
!=
testcase
.
ResponseAllowOrigin
{
t
.
Errorf
(
"expected '%s' got '%s'"
,
testcase
.
ResponseAllowOrigin
,
headerAccessControlPreflight
)
}
//Perform request
rr
:=
httptest
.
NewRecorder
()
req
:=
httptest
.
NewRequest
(
"GET"
,
"/.well-kown/openid-configuration"
,
nil
)
req
.
Header
.
Set
(
"Origin"
,
testcase
.
Origin
)
discoveryHandler
.
ServeHTTP
(
rr
,
req
)
if
rr
.
Code
!=
http
.
StatusOK
{
t
.
Errorf
(
"expected 200 got %d"
,
rr
.
Code
)
}
headerAccessControl
:=
rr
.
HeaderMap
.
Get
(
"Access-Control-Allow-Origin"
)
if
headerAccessControl
!=
testcase
.
ResponseAllowOrigin
{
t
.
Errorf
(
"expected '%s' got '%s'"
,
testcase
.
ResponseAllowOrigin
,
headerAccessControl
)
}
}
}
server/server.go
View file @
fe93f60a
...
...
@@ -13,6 +13,7 @@ import (
"golang.org/x/net/context"
"github.com/Sirupsen/logrus"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
"github.com/coreos/dex/connector"
...
...
@@ -42,10 +43,10 @@ type Config struct {
// flow. If no response types are supplied this value defaults to "code".
SupportedResponseTypes
[]
string
// List of allowed origins for CORS requests on discovery endpoint.
// List of allowed origins for CORS requests on discovery
, token and keys
endpoint.
// If none are indicated, CORS requests are disabled. Passing in "*" will allow any
// domain.
Discovery
AllowedOrigins
[]
string
AllowedOrigins
[]
string
// If enabled, the server won't prompt the user to approve authorization requests.
// Logging in implies approval.
...
...
@@ -116,8 +117,6 @@ type Server struct {
supportedResponseTypes
map
[
string
]
bool
discoveryAllowedOrigins
[]
string
now
func
()
time
.
Time
idTokensValidFor
time
.
Duration
...
...
@@ -185,16 +184,15 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy)
}
s
:=
&
Server
{
issuerURL
:
*
issuerURL
,
connectors
:
make
(
map
[
string
]
Connector
),
storage
:
newKeyCacher
(
c
.
Storage
,
now
),
supportedResponseTypes
:
supported
,
discoveryAllowedOrigins
:
c
.
DiscoveryAllowedOrigins
,
idTokensValidFor
:
value
(
c
.
IDTokensValidFor
,
24
*
time
.
Hour
),
skipApproval
:
c
.
SkipApprovalScreen
,
now
:
now
,
templates
:
tmpls
,
logger
:
c
.
Logger
,
issuerURL
:
*
issuerURL
,
connectors
:
make
(
map
[
string
]
Connector
),
storage
:
newKeyCacher
(
c
.
Storage
,
now
),
supportedResponseTypes
:
supported
,
idTokensValidFor
:
value
(
c
.
IDTokensValidFor
,
24
*
time
.
Hour
),
skipApproval
:
c
.
SkipApprovalScreen
,
now
:
now
,
templates
:
tmpls
,
logger
:
c
.
Logger
,
}
for
_
,
conn
:=
range
c
.
Connectors
{
...
...
@@ -205,24 +203,29 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy)
handleFunc
:=
func
(
p
string
,
h
http
.
HandlerFunc
)
{
r
.
HandleFunc
(
path
.
Join
(
issuerURL
.
Path
,
p
),
h
)
}
handle
:=
func
(
p
string
,
h
http
.
Handler
)
{
r
.
Handle
(
path
.
Join
(
issuerURL
.
Path
,
p
),
h
)
}
handlePrefix
:=
func
(
p
string
,
h
http
.
Handler
)
{
prefix
:=
path
.
Join
(
issuerURL
.
Path
,
p
)
r
.
PathPrefix
(
prefix
)
.
Handler
(
http
.
StripPrefix
(
prefix
,
h
))
}
handleWithCORS
:=
func
(
p
string
,
h
http
.
HandlerFunc
)
{
var
handler
http
.
Handler
=
h
if
len
(
c
.
AllowedOrigins
)
>
0
{
corsOption
:=
handlers
.
AllowedOrigins
(
c
.
AllowedOrigins
)
handler
=
handlers
.
CORS
(
corsOption
)(
handler
)
}
r
.
Handle
(
path
.
Join
(
issuerURL
.
Path
,
p
),
handler
)
}
r
.
NotFoundHandler
=
http
.
HandlerFunc
(
http
.
NotFound
)
discoveryHandler
,
err
:=
s
.
discoveryHandler
()
if
err
!=
nil
{
return
nil
,
err
}
handle
(
"/.well-known/openid-configuration"
,
discoveryHandler
)
handle
WithCORS
(
"/.well-known/openid-configuration"
,
discoveryHandler
)
// TODO(ericchiang): rate limit certain paths based on IP.
handle
Func
(
"/token"
,
s
.
handleToken
)
handle
Func
(
"/keys"
,
s
.
handlePublicKeys
)
handle
WithCORS
(
"/token"
,
s
.
handleToken
)
handle
WithCORS
(
"/keys"
,
s
.
handlePublicKeys
)
handleFunc
(
"/auth"
,
s
.
handleAuthorization
)
handleFunc
(
"/auth/{connector}"
,
s
.
handleConnectorLogin
)
handleFunc
(
"/callback"
,
s
.
handleConnectorCallback
)
...
...
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