Comment intégrer l'authentification sms keycloak par API?

Oct 16 2020

J'ai un serveur keycloak et une application Laravel utilisant KeycloakProvider personnalisé:

public function loginByEmail(string $email, string $password): SsoTokens
{
    try {
        $data = $this->realmEndpoint->makeRequest(
            HttpClientProvider::METHOD_POST,
            self::KEYCLOAK_AUTH_URL,
            [
                'client_id' => config('services.keycloak.realm_client'),
                'client_secret' => config('services.keycloak.realm_secret'),
                'grant_type' => 'password',
                'username' => $email, 'password' => $password,
                'scope' => 'openid'
            ]
        );
    } catch (TransportUnauthorizedException $e) { throw new UnauthorizedException($e);
    } catch (HttpClientException $e) { throw new TransportException($e);
    }

    return $this->extractTokens($data);
}

Maintenant, mon objectif est de configurer l'authentification SMS de base par le numéro de téléphone mobile de l'utilisateur. J'ai trouvé des outils ( 1 , 2 ), mais ils ne fournissent pas d'API, juste des pages HTML. Y a-t-il une solution?

Réponses

1 AndreyD Nov 12 2020 at 17:07

J'ai trouvé une solution. Pour vous connecter sans connaître le mot de passe de quelqu'un:

  1. Envoyer un SMS;
  2. Confirmez le numéro de téléphone par un code;
  3. Obtenez l'ID keycloak d'un utilisateur cible;
  4. Connectez-vous en tant qu'utilisateur ayant le droit d' usurper l'identité ;
  5. Échangez des jetons avec un utilisateur cible.

TOKEN_EXCHANGE fonction keycloak requise.

Étapes 1 à 3 que j'ai implémentées avec Laravel, étapes 4 à 5 avec les API Keycloak:

public function loginByUserId(string $userId): SsoTokens { try { $impersonatorData = $this->realmEndpoint->makeRequest( HttpClientProvider::METHOD_POST, self::KEYCLOAK_AUTH_URL, [ 'client_id' => config('services.keycloak.realm_client'), 'client_secret' => config('services.keycloak.realm_secret'), 'grant_type' => 'password', 'username' => config('services.keycloak.admin_username'), 'password' => config('services.keycloak.admin_password'), 'scope' => 'openid', ] ); $data = $this->realmEndpoint->makeRequest( HttpClientProvider::METHOD_POST, self::KEYCLOAK_AUTH_URL, [ 'client_id' => config('services.keycloak.realm_client'), 'client_secret' => config('services.keycloak.realm_secret'), 'grant_type' => 'urn:ietf:params:oauth:grant-type:token-exchange', 'requested_subject' => $userId,
                    'subject_token' => $impersonatorData['access_token'], 'scope' => 'openid', ] ); } catch (TransportUnauthorizedException $e) {
            throw new UnauthorizedException($e); } catch (HttpClientException $e) {
            throw new TransportException($e); } return $this->extractTokens($data);
    }