mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 08:58:41 +00:00
Make end-user auth check backwards-compatible (#35293)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #35214 # Details Pursuant to the discussion in https://fleetdm.slack.com/archives/C084F4MKYSJ/p1762352268815269, this PR updates the `/orbit/enroll` API handler such that: * IF end-user auth is configured for the team the host is enrolling to, * AND the host's user has not completed authentication, * AND the Orbit version making the enroll request does not support prompting for end-user authentication, * THEN the host will not be blocked from enrolling. # Checklist for submitter If some of the following don't apply, delete the relevant line. ## Testing - [ ] Added/updated automated tests working on this, will post when done - [X] QA'd all new/changed functionality manually * Set up my local Fleet instance with end-user auth enabled for setup experience on a team * With this branch running as Fleet server, ran Orbit also on this branch and attempted to enroll to that team * Verified that the SSO window was opened in my browser * With Fleet server still running this branch, switched my local working tree to `rc-minor-fleet-v4.75.0` and ran Orbit again * Verified that the host enrolled successfully and error messages appeared in the fleet server logs.
This commit is contained in:
parent
5aaba26d6f
commit
ad517ab731
4 changed files with 38 additions and 2 deletions
|
|
@ -94,6 +94,9 @@ const (
|
|||
// CapabilityMacOSWebSetupExperience denotes the ability of the server to support
|
||||
// a web-based setup experience UI for macOS devices
|
||||
CapabilityMacOSWebSetupExperience Capability = "macos_web_setup_experience"
|
||||
// CapabilityEndUserAuth denotes the ability of the client to authenticate
|
||||
// the end user against the Fleet server (e.g. SSO) before enrolling
|
||||
CapabilityEndUserAuth Capability = "end_user_auth"
|
||||
)
|
||||
|
||||
func GetServerOrbitCapabilities() CapabilityMap {
|
||||
|
|
@ -121,6 +124,7 @@ func GetOrbitClientCapabilities() CapabilityMap {
|
|||
return CapabilityMap{
|
||||
CapabilityEscrowBuddy: {},
|
||||
CapabilitySetupExperience: {},
|
||||
CapabilityEndUserAuth: {},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -139,6 +139,26 @@ func newNoAuthEndpointer(svc fleet.Service, opts []kithttp.ServerOption, r *mux.
|
|||
}
|
||||
}
|
||||
|
||||
func newOrbitNoAuthEndpointer(svc fleet.Service, opts []kithttp.ServerOption, r *mux.Router,
|
||||
versions ...string,
|
||||
) *eu.CommonEndpointer[eu.HandlerFunc] {
|
||||
// Add the capabilities reported by Orbit to the request context
|
||||
opts = append(opts, capabilitiesContextFunc())
|
||||
|
||||
return &eu.CommonEndpointer[eu.HandlerFunc]{
|
||||
EP: &endpointer{
|
||||
svc: svc,
|
||||
},
|
||||
MakeDecoderFn: makeDecoder,
|
||||
EncodeFn: encodeResponse,
|
||||
Opts: opts,
|
||||
AuthFunc: auth.UnauthenticatedRequest,
|
||||
FleetService: svc,
|
||||
Router: r,
|
||||
Versions: versions,
|
||||
}
|
||||
}
|
||||
|
||||
func badRequest(msg string) error {
|
||||
return &fleet.BadRequestError{Message: msg}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -987,7 +987,9 @@ func attachFleetAPIRoutes(r *mux.Router, svc fleet.Service, config config.FleetC
|
|||
// This endpoint is unauthenticated and is used by to retrieve the MDM enrollment Terms of Use
|
||||
neWindowsMDM.GET(microsoft_mdm.MDE2TOSPath, mdmMicrosoftTOSEndpoint, MDMWebContainer{})
|
||||
|
||||
ne.POST("/api/fleet/orbit/enroll", enrollOrbitEndpoint, contract.EnrollOrbitRequest{})
|
||||
// These endpoints are unauthenticated and made from orbit, and add the orbit capabilities header.
|
||||
neOrbit := newOrbitNoAuthEndpointer(svc, opts, r, apiVersions...)
|
||||
neOrbit.POST("/api/fleet/orbit/enroll", enrollOrbitEndpoint, contract.EnrollOrbitRequest{})
|
||||
|
||||
ne.GET("/api/_version_/fleet/software/titles/{title_id:[0-9]+}/in_house_app", getInHouseAppPackageEndpoint, getInHouseAppPackageRequest{})
|
||||
ne.GET("/api/_version_/fleet/software/titles/{title_id:[0-9]+}/in_house_app/manifest", getInHouseAppManifestEndpoint, getInHouseAppManifestRequest{})
|
||||
|
|
|
|||
|
|
@ -197,7 +197,17 @@ func (svc *Service) EnrollOrbit(ctx context.Context, hostInfo fleet.OrbitHostInf
|
|||
return "", fleet.OrbitError{Message: "failed to get IdP account: " + err.Error()}
|
||||
}
|
||||
if idpAccount == nil {
|
||||
return "", fleet.NewOrbitIDPAuthRequiredError()
|
||||
// If the Orbit client doesn't support end user auth, complain loudly and let the host enroll.
|
||||
mp, ok := capabilities.FromContext(ctx)
|
||||
//nolint:gocritic // ignore ifElseChain
|
||||
if !ok {
|
||||
level.Error(svc.logger).Log("msg", "!!! ERR_ALLOWING_UNAUTHENTICATED: host is not authenticated, but fleet could not determine whether orbit supports end-user authentication. proceeding with enrollment. !!! ", "host_uuid", hostInfo.HardwareUUID)
|
||||
} else if !mp.Has(fleet.CapabilityEndUserAuth) {
|
||||
level.Error(svc.logger).Log("msg", "!!! ERR_ALLOWING_UNAUTHENTICATED: host is not authenticated, but connected with an orbit version that does not support end user authentication. proceeding with enrollment. !!! ", "host_uuid", hostInfo.HardwareUUID)
|
||||
} else {
|
||||
// Otherwise report the unauthenticated host and let Orbit handle it (e.g. by prompting the user to authenticate).
|
||||
return "", fleet.NewOrbitIDPAuthRequiredError()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue