better support for /device/callback redirect uris with public clients.
Signed-off-by: justin-slowik <justin.slowik@thermofisher.com>
This commit is contained in:
parent
f6d8427f32
commit
9882ea453f
@ -98,8 +98,9 @@ staticClients:
|
||||
secret: ZXhhbXBsZS1hcHAtc2VjcmV0
|
||||
# - id: example-device-client
|
||||
# redirectURIs:
|
||||
# - /dex/device/callback
|
||||
# - /device/callback
|
||||
# name: 'Static Client for Device Flow'
|
||||
# public: true
|
||||
connectors:
|
||||
- type: mockCallback
|
||||
id: mock
|
||||
|
@ -374,7 +374,7 @@ func (s *Server) verifyUserCode(w http.ResponseWriter, r *http.Request) {
|
||||
q.Set("client_secret", deviceRequest.ClientSecret)
|
||||
q.Set("state", deviceRequest.UserCode)
|
||||
q.Set("response_type", "code")
|
||||
q.Set("redirect_uri", path.Join(s.issuerURL.Path, "/device/callback"))
|
||||
q.Set("redirect_uri", "/device/callback")
|
||||
q.Set("scope", strings.Join(deviceRequest.Scopes, " "))
|
||||
u.RawQuery = q.Encode()
|
||||
|
||||
|
@ -128,7 +128,7 @@ func TestDeviceCallback(t *testing.T) {
|
||||
baseAuthCode := storage.AuthCode{
|
||||
ID: "somecode",
|
||||
ClientID: "testclient",
|
||||
RedirectURI: "/device/callback",
|
||||
RedirectURI: deviceCallbackURI,
|
||||
Nonce: "",
|
||||
Scopes: []string{"openid", "profile", "email"},
|
||||
ConnectorID: "mock",
|
||||
@ -194,7 +194,7 @@ func TestDeviceCallback(t *testing.T) {
|
||||
testAuthCode: storage.AuthCode{
|
||||
ID: "somecode",
|
||||
ClientID: "testclient",
|
||||
RedirectURI: "/device/callback",
|
||||
RedirectURI: deviceCallbackURI,
|
||||
Nonce: "",
|
||||
Scopes: []string{"openid", "profile", "email"},
|
||||
ConnectorID: "pic",
|
||||
@ -210,7 +210,7 @@ func TestDeviceCallback(t *testing.T) {
|
||||
testAuthCode: storage.AuthCode{
|
||||
ID: "somecode",
|
||||
ClientID: "testclient",
|
||||
RedirectURI: "/device/callback",
|
||||
RedirectURI: deviceCallbackURI,
|
||||
Nonce: "",
|
||||
Scopes: []string{"openid", "profile", "email"},
|
||||
ConnectorID: "pic",
|
||||
@ -336,7 +336,7 @@ func TestDeviceCallback(t *testing.T) {
|
||||
client := storage.Client{
|
||||
ID: "testclient",
|
||||
Secret: "",
|
||||
RedirectURIs: []string{"/device/callback"},
|
||||
RedirectURIs: []string{deviceCallbackURI},
|
||||
}
|
||||
if err := s.storage.CreateClient(client); err != nil {
|
||||
t.Fatalf("failed to create client: %v", err)
|
||||
|
@ -114,6 +114,10 @@ const (
|
||||
scopeCrossClientPrefix = "audience:server:client_id:"
|
||||
)
|
||||
|
||||
const (
|
||||
deviceCallbackURI = "/device/callback"
|
||||
)
|
||||
|
||||
const (
|
||||
redirectURIOOB = "urn:ietf:wg:oauth:2.0:oob"
|
||||
)
|
||||
@ -433,6 +437,9 @@ func (s *Server) parseAuthorizationRequest(r *http.Request) (*storage.AuthReques
|
||||
description := fmt.Sprintf("Unregistered redirect_uri (%q).", redirectURI)
|
||||
return nil, &authErr{"", "", errInvalidRequest, description}
|
||||
}
|
||||
if redirectURI == deviceCallbackURI && client.Public {
|
||||
redirectURI = s.issuerURL.Path + deviceCallbackURI
|
||||
}
|
||||
|
||||
// From here on out, we want to redirect back to the client with an error.
|
||||
newErr := func(typ, format string, a ...interface{}) *authErr {
|
||||
@ -574,7 +581,7 @@ func validateRedirectURI(client storage.Client, redirectURI string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
if redirectURI == redirectURIOOB {
|
||||
if redirectURI == redirectURIOOB || redirectURI == deviceCallbackURI{
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -309,7 +309,7 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy)
|
||||
handleFunc("/device/auth/verify_code", s.verifyUserCode)
|
||||
handleFunc("/device/code", s.handleDeviceCode)
|
||||
handleFunc("/device/token", s.handleDeviceToken)
|
||||
handleFunc("/device/callback", s.handleDeviceCallback)
|
||||
handleFunc(deviceCallbackURI, s.handleDeviceCallback)
|
||||
r.HandleFunc(path.Join(issuerURL.Path, "/callback"), func(w http.ResponseWriter, r *http.Request) {
|
||||
// Strip the X-Remote-* headers to prevent security issues on
|
||||
// misconfigured authproxy connector setups.
|
||||
|
@ -1317,8 +1317,8 @@ func TestOAuth2DeviceFlow(t *testing.T) {
|
||||
//Add the Clients to the test server
|
||||
client := storage.Client{
|
||||
ID: clientID,
|
||||
//Secret: "testclientsecret",
|
||||
RedirectURIs: []string{"/non-root-path/device/callback"},
|
||||
RedirectURIs: []string{deviceCallbackURI},
|
||||
Public: true,
|
||||
}
|
||||
if err := s.storage.CreateClient(client); err != nil {
|
||||
t.Fatalf("failed to create client: %v", err)
|
||||
@ -1421,7 +1421,7 @@ func TestOAuth2DeviceFlow(t *testing.T) {
|
||||
ClientSecret: client.Secret,
|
||||
Endpoint: p.Endpoint(),
|
||||
Scopes: requestedScopes,
|
||||
RedirectURL: "/non-root-path/device/callback",
|
||||
RedirectURL: deviceCallbackURI,
|
||||
}
|
||||
if len(tc.scopes) != 0 {
|
||||
oauth2Config.Scopes = tc.scopes
|
||||
|
Reference in New Issue
Block a user