Pre-check SSO by domain
Validate that a user's email domain has an active SSO connection before redirecting to prevent dead-end redirects and improve user experience.
When using discovery through loginHint, validate that the user’s email domain has an active SSO connection before redirecting. This prevents dead-end redirects and improves user experience by routing users to the correct authentication path.
When to use domain pre-checking
Section titled “When to use domain pre-checking”Use domain pre-checking when:
- You implement identifier-driven or SSO button flows that collect email first
- You infer SSO availability from the user’s email domain
- You want to show helpful error messages for domains without SSO
Skip this check when:
- You already pass
organizationIdexplicitly (you know the organization) - You implement organization-specific pages where SSO is always available
Implementation workflow
Section titled “Implementation workflow”-
Capture the user’s email and extract the domain
Section titled “Capture the user’s email and extract the domain”First, collect the user’s email address through your login form.
Login form handler // Extract domain from user's emailconst email = req.body.email;const domain = email.split('@')[1]; // e.g., "acmecorp.com" -
Query for SSO connections by domain
Section titled “Query for SSO connections by domain”Use the Scalekit API to check if the domain has an active SSO connection configured.
Express.js // Use case: Check if user's domain has SSO before redirectingapp.post('/auth/check-sso', async (req, res) => {const { email } = req.body;const domain = email.split('@')[1];try {// Query Scalekit for connections matching this domainconst connections = await scalekit.connection.listConnections({domain: domain});if (connections.length > 0) {// Domain has active SSO - redirect to SSO loginconst authorizationURL = scalekit.getAuthorizationUrl(process.env.REDIRECT_URI,{ loginHint: email });res.json({ ssoAvailable: true, redirectUrl: authorizationURL });} else {// No SSO configured - route to password or social loginres.json({ ssoAvailable: false, message: 'Please use password login' });}} catch (error) {console.error('Failed to check SSO availability:', error);res.status(500).json({ error: 'sso_check_failed' });}});Flask # Use case: Check if user's domain has SSO before redirecting@app.route('/auth/check-sso', methods=['POST'])def check_sso():data = request.get_json()email = data.get('email')domain = email.split('@')[1]try:# Query Scalekit for connections matching this domainconnections = scalekit_client.connection.list_connections(domain=domain)if len(connections) > 0:# Domain has active SSO - redirect to SSO loginauthorization_url = scalekit_client.get_authorization_url(redirect_uri=os.getenv("REDIRECT_URI"),options=AuthorizationUrlOptions(login_hint=email))return jsonify({'ssoAvailable': True,'redirectUrl': authorization_url})else:# No SSO configured - route to password or social loginreturn jsonify({'ssoAvailable': False,'message': 'Please use password login'})except Exception as error:print(f"Failed to check SSO availability: {error}")return jsonify({'error': 'sso_check_failed'}), 500Gin // Use case: Check if user's domain has SSO before redirectingfunc checkSSOHandler(c *gin.Context) {var body struct {Email string `json:"email"`}c.BindJSON(&body)domain := strings.Split(body.Email, "@")[1]// Query Scalekit for connections matching this domainconnections, err := scalekitClient.Connection.ListConnections(&scalekit.ListConnectionsOptions{Domain: domain,},)if err != nil {log.Printf("Failed to check SSO availability: %v", err)c.JSON(http.StatusInternalServerError, gin.H{"error": "sso_check_failed"})return}if len(connections) > 0 {// Domain has active SSO - redirect to SSO loginauthorizationURL, _ := scalekitClient.GetAuthorizationUrl(os.Getenv("REDIRECT_URI"),scalekit.AuthorizationUrlOptions{LoginHint: body.Email,},)c.JSON(http.StatusOK, gin.H{"ssoAvailable": true,"redirectUrl": authorizationURL,})} else {// No SSO configured - route to password or social loginc.JSON(http.StatusOK, gin.H{"ssoAvailable": false,"message": "Please use password login",})}}Spring Boot // Use case: Check if user's domain has SSO before redirecting@PostMapping(path = "/auth/check-sso")public ResponseEntity<Map<String, Object>> checkSSOHandler(@RequestBody CheckSSORequest body) {String email = body.getEmail();String domain = email.split("@")[1];try {// Query Scalekit for connections matching this domainListConnectionsResponse connections = scalekitClient.connection().listConnections(new ListConnectionsOptions().setDomain(domain));if (!connections.getConnections().isEmpty()) {// Domain has active SSO - redirect to SSO loginString authorizationURL = scalekitClient.authentication().getAuthorizationUrl(System.getenv("REDIRECT_URI"),new AuthorizationUrlOptions().setLoginHint(email)).toString();Map<String, Object> response = new HashMap<>();response.put("ssoAvailable", true);response.put("redirectUrl", authorizationURL);return ResponseEntity.ok(response);} else {// No SSO configured - route to password or social loginMap<String, Object> response = new HashMap<>();response.put("ssoAvailable", false);response.put("message", "Please use password login");return ResponseEntity.ok(response);}} catch (Exception error) {System.err.println("Failed to check SSO availability: " + error.getMessage());return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Collections.singletonMap("error", "sso_check_failed"));}} -
Route users based on SSO availability
Section titled “Route users based on SSO availability”Based on the API response, either redirect to SSO or show alternative authentication options.
Client-side routing // Handle the response from your backendconst response = await fetch('/auth/check-sso', {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify({ email: userEmail })});const data = await response.json();if (data.ssoAvailable) {// Redirect to SSO loginwindow.location.href = data.redirectUrl;} else {// Show password login or social authentication optionsshowPasswordLoginForm();}