[JAVA] Essayez d'ajouter l'authentification SMS (à l'aide de Twilio) au processus d'authentification Keycloak

introduction

Aujourd'hui, le 5ème jour est la personnalisation de Keycloak. Pour une description de Keycloak, voir Qu'est-ce que Keycloak. Cet article présente Keycloak dans le [Keycloak by OpenStandia Advent Calendar 2017] de l'année dernière (https://qiita.com/advent-calendar/2017/keycloak-by-openstandia). J'ai également participé au calendrier de l'Avent Keycloak de l'année dernière et j'ai écrit un article sur Keycloak Customization Points. Cette fois, nous allons récupérer la fonction d'authentification (Authentication SPI) dans ce point de personnalisation et SMS pour le traitement de l'authentification. Personnalisons-le pour ajouter une fonction d'authentification (vérification d'identité).

SMS? Authentification SMS?

SMS (Short Message Service) est un service qui vous permet d'envoyer et de recevoir des messages courts par numéro de téléphone. L'authentification SMS consiste à effectuer une authentification (vérification d'identité) à l'aide de SMS. L'image suivante est exprimée dans une image.

SMS認証イメージ.png

En envoyant et en confirmant le code de vérification au numéro de téléphone enregistré de M. A séparément de la connexion ID / PWD, vous pouvez confirmer votre identité de manière plus fiable, de sorte que vous pouvez augmenter la probabilité d'empêcher une connexion non autorisée d'un tiers. Je vais.

Les services d'envoi et de réception de SMS sont fournis par Twilio, nexmo, [Amazon SNS]( Il en existe plusieurs tels que https://aws.amazon.com/jp/sns/), mais ** Twilio ** </ font> est utilisé pour ce service de transmission / réception de SMS. Je vais.

Qu'est-ce que Twilio?

20171206203748.png

Twilio est une société de communication cloud située à San Francisco qui fournit des services d'envoi et de réception d'appels téléphoniques et de messages texte à l'aide de l'API du service WEB. Au Japon, KDDI est l'agence et document japonais est également ouvert au public, donc je pense qu'il sera facile d'entrer lors de son utilisation pour la première fois.

En passant, le [Calendrier de l'Avent] de Twilio (https://qiita.com/advent-calendar/2018/twilio) a également été enregistré cette année. (Enregistré chaque année depuis 2015) Twilio fournit diverses API de communication autres que l'envoi et la réception de SMS, veuillez donc vous y référer si vous êtes intéressé.

Préparation préalable

Créer un compte Twilio

Pour utiliser l'authentification SMS de Twilio, vous avez besoin d'un compte Twilio (pour être exact, vous avez besoin d'API-KEY pour envoyer et recevoir des SMS). Compte d'essai gratuit peut être enregistré et gratuit jusqu'à un certain montant dans Twilio Il est possible d'utiliser dans. Lorsqu'un certain montant est atteint, le compte sera automatiquement suspendu et une notification de mise à niveau sera envoyée au compte payant.

Vous ne serez pas facturé sauf si vous passez à un compte payant (à partir de décembre 2018), mais cela peut changer à l'avenir, veuillez donc vérifier les conditions d'utilisation lors de votre inscription. L'enregistrement en lui-même est facile, je pense donc que vous pouvez procéder normalement. La vérification du numéro de téléphone (SMS) aura lieu lors de l'inscription, alors préparez un téléphone pouvant recevoir des SMS. (Les frais de communication SMS sont à la charge du destinataire.)

Obtenez API-KEY pour Twilio

Après avoir créé un compte, lorsque l'écran TOP est affiché, allez dans «Écran supérieur» ⇒ «Vérification du numéro de téléphone» ⇒ «Vérification du numéro de téléphone Tableau de bord du projet» ⇒ «Vérifier» et l'écran suivant s'affichera. Procédons dans l'ordre des nombres.

verify.png

  • 「1. Let’s verify a phone number on your Twilio account」

  • Ici, vérifiez à nouveau le numéro de téléphone.

  • 「2. Create an application and get your API credentials」

  • Créer une application et une API. Une fois que vous aurez créé une application, vous pourrez vérifier et mettre à jour l'historique de transmission / réception de SMS et API-KEY.

  • 「3. Send your first Verify code」

  • Utilisez l'application API-KEY créée ci-dessus pour envoyer le code de vérification par SMS avec cURL. Le contenu de la demande sera affiché comme indiqué ci-dessous, vous pouvez donc également vérifier l'API-KEY ici. (Vous pouvez également vérifier à partir de l'écran de réglage)

verify2.png

  • 「4. Get verified」
  • Vérifiez le cURL pour voir si le code de vérification que vous avez reçu est correct.

Ceci termine les préparatifs côté Twilio.

Confirmation de connexion avant personnalisation

Vérifiez le processus de connexion avant de personnaliser. Vous pouvez confirmer votre connexion en accédant à l'écran de gestion de compte.

  • Afficher l'écran de gestion du compte
  • http: // localhost: 8080 / auth / realms / nom de domaine / compte

Login.png

  • Connexion réussie à l'écran de gestion de compte

Login_OK.png

J'ai confirmé que je ne pouvais me connecter qu'en entrant mon nom d'utilisateur / mot de passe.

Personnalisation de la fonction d'authentification

Personnalisez la fonction d'authentification. L'ordre de travail est le suivant.

  1. Créer un écran (thèmes)
  2. Créez un module d'authentification SMS
  3. Refléter le module de personnalisation dans Keycloak
  4. Démarrez Keycloak
  5. Reflect settings (console de gestion)

Créer un écran (thèmes)

J'ai créé un nouveau thème appelé "openstandia" pour créer deux écrans (.ftl) et un fichier de message ( .properties). Le code source est ici. Pour le refléter, placez le dossier ʻopenstandia du code source sous KEYCLOAK_HOME / themes / ʻ tel quel, et il sera reflété.

  • Écran de saisie du code de vérification (sms-validation.ftl)

verifyinput.png

  • Écran d'erreur de code d'authentification (sms-validation-error.ftl)

verifyerror.png

  • Fichier de messages (* .properties)
  • messages_ja.properties (messages japonais)
  • messages_en.properties

Nous avons préparé deux fichiers de messages, l'un pour le japonais (jp) et l'autre pour l'anglais (en). La langue correspondante est définie dans locales de theme.properties ..

_KEYCLOAK_HOME_/themes/Nom du thème/login/theme.properties


parent=keycloak
import=common/keycloak
locales=en,ja

Pour savoir comment personnaliser les thèmes, voir "[Organiser les thèmes de personnalisation Keycloak - À propos des thèmes] de l'année dernière](https://qiita.com/yoonis/items/298d580f7e93e56ddf6a#themes%E3%81%AB%E3%81%A4" % E3% 81% 84% E3% 81% A6) », veuillez donc vous y référer.

Créer un module d'authentification SMS

Créez un module d'authentification SMS. Auparavant, au moment de "Obtenir l'API-KEY de Twilio", nous avons émis le code de vérification et confirmé le code de vérification avec cURL, mais nous l'exécuterons dans le module de vérification par SMS.

  • Le SPI correspondant au module d'authentification SMS est ** Authentication SPI **
  • ʻImplements ʻinterface est ʻorg.keycloak.authentication.Authenticator`

Commencez par créer les deux classes de base suivantes.

  • Classe de module d'authentification SMS

    • SMSAuthenticator implements Authenticator
  • Classe d'usine de classe de module d'authentification SMS

    • SMSAuthenticatorFactory implements AuthenticatorFactory, ConfigurableAuthenticatorFactory

Implémentation SMSAuthenticatorFactory

  • Méthode getId ()
  • Renvoie l'ID du fournisseur. (unique)
	public static final String PROVIDER_ID = "sms-authenticator-with-twilio";

	public String getId() {
		return PROVIDER_ID;
	}
  • Méthode getDisplayType ()
  • Renvoie le nom d'affichage de l'écran.
	public String getDisplayType() {
		return "Twilio SMS Authentication";
	}
  • Méthode ʻIsConfigurable () `

  • Renvoie s'il s'agit d'un authentificateur qui peut être défini à l'écran (console d'administration). Renvoie «true» s'il y a des éléments à saisir à partir de l'écran. Cette fois, API-KEY etc. sera entré, donc true

  • Méthode getConfigProperties ()

  • Définition de l'élément d'entrée de l'écran (console d'administration). Je souhaite saisir la clé API, les chiffres du code d'authentification, les paramètres de proxy, etc. à partir de la console de gestion, alors définissez-les ici.

	private static final List<ProviderConfigProperty> configProperties;
	static {
        configProperties = ProviderConfigurationBuilder
                .create()
                .property()
                .name(SMSAuthContstants.CONFIG_SMS_API_KEY)
                .label("API-KEY")
                .type(ProviderConfigProperty.STRING_TYPE)
                .helpText("")
                .add()

                ......

                .property()
                .name(SMSAuthContstants.CONFIG_CODE_LENGTH)
                .label("Code Length")
                .type(ProviderConfigProperty.STRING_TYPE)
                .helpText("")
                .defaultValue(4)
                .add()

                .build();
	}

    ......

	public List<ProviderConfigProperty> getConfigProperties() {
		return configProperties;
	}

  • Méthode getRequirementChoices ()
  • Renvoie le type d'exigence à prendre en charge. Cette fois, réglez uniquement requis (REQUIS) et désactivé (DISABLED). D'autres sont ALTERNATIFS et OPTIONNELS.
	private static final AuthenticationExecutionModel.Requirement[] REQUIREMENT_CHOICES = {
			AuthenticationExecutionModel.Requirement.REQUIRED,
			AuthenticationExecutionModel.Requirement.DISABLED
	};

	public Requirement[] getRequirementChoices() {
		return REQUIREMENT_CHOICES;
	}
  • Afin d'enregistrer la classe SMSAuthenticatorFactory, placez un fichier de définition qui décrit le nom de classe d'usine comme indiqué ci-dessous sous META-INF.

META-INF/services/org.keycloak.authentication.AuthenticatorFactory


jp.openstandia.keycloak.authenticator.SMSAuthenticatorFactory

Implémentation de SMS Authenticator

  • Méthode ʻAuthenticate (AuthenticationFlowContext context) `
  • Processus d'authentification, implémentez le processus de transmission du code d'authentification SMS avec cette méthode
public void authenticate(AuthenticationFlowContext context) {

	......
	
	if (sendVerify.sendSMS(phoneNumber)) { //Envoyer un SMS

		Response challenge = context.form().createForm("sms-validation.ftl");
		context.challenge(challenge);

	} else {

        //Renvoie un écran d'erreur lorsque le SMS échoue
		Response challenge = context.form().setError(new FormMessage("sendSMSCodeErrorMessage"))
				.createForm("sms-validation-error.ftl");
		context.challenge(challenge);
	}

	......
}

Ce qu'il faut noter ici, c'est comment renvoyer le résultat. Réglez l'écran pour revenir aux informations de réponse (Challenge) (createForm) sur context. Vous pouvez également définir un message d'erreur (setError) si une erreur se produit. La valeur de réglage de setError`` new FormMessage (" sendSMSCodeErrorMessage ") sendSMSCodeErrorMessage est les messages des thèmes. / openstandia / login / messages) Il s'agit de la clé de message définie dans le fichier messages_xx_properties.

  • Méthode ʻAction (AuthenticationFlowContext context) `
  • Implémentation du processus pour vérifier le code d'authentification entré à partir de l'écran avec cette méthode
public void action(AuthenticationFlowContext context) {

	MultivaluedMap<String, String> inputData = context.getHttpRequest().getDecodedFormParameters();
	String enteredCode = inputData.getFirst("smsCode");

	......
	
	if (sendVerify.verifySMS(phoneNumber, enteredCode)) { //Confirmation du code de vérification
		logger.info("verify code check : OK");
        //Lorsque le code de vérification est OK
		context.success();

	} else {
        //Renvoie un écran d'erreur lorsque l'authentification échoue
		Response challenge = context.form()
				.setAttribute("username", context.getAuthenticationSession().getAuthenticatedUser().getUsername())
				.setError(new FormMessage("invalidSMSCodeMessage")).createForm("sms-validation-error.ftl");
		context.challenge(challenge);
		}

	......
}

Encore une fois, faites attention à la façon de renvoyer le résultat. Si la vérification du code de vérification réussit avec verifySMS, ce résultat de vérification sera OK avec context.success (). En cas d'erreur, comme la méthode ʻauthenticate, définissez l'écran d'affichage et le message d'erreur dans Response (Challenge) et réglez-le sur context`.

Traitement de la transmission / confirmation par SMS

Le processus de transmission SMS / confirmation de code implémenté dans le "SMSAuthenticator" ci-dessus a été implémenté en utilisant l'API de Twilio en utilisant "HttpsURLConnection". Le traitement de la transmission SMS (appel Twilio API) est [ici](https://github.com/sangyoon-lee/keycloak-sms-authenticator/blob/master/src/main/java/jp/openstandia/keycloak/authenticator/ api / SMSSendVerify.java)

C'est tout pour la création de modules. Seules les méthodes importantes ont été présentées ici. Le code source de l'exemple de module est publié sur GitHub, veuillez donc vérifier le code source pour les paramètres détaillés. Le code source est ici

Refléter le module de personnalisation dans Keycloak

Reflète le fichier créé dans Keycloak.

Placement des thèmes

Placez le fichier Themes créé (pour chaque dossier Openstandia) dans _KEYCLOAK_HOME_ / themes /. S'il a déjà été placé lors de "Créer un écran (thèmes)", sautez-le.

Placement du module d'authentification (.jar)

Empaquetez le module d'authentification que vous avez créé avec mvn package et placez le fichier jar dans _KEYCLOAK_HOME_ / standalone / deployments /.

Démarrer Keycloak

Après avoir déployé tous les modules de personnalisation, démarrez Keycloak.

Reflect settings (console de gestion)

Réflexion des thèmes

Reflète les thèmes. Cela se fait à partir de l'onglet "Paramètres du royaume" - "Thèmes". Puisque seul le thème de connexion est créé cette fois, changez le "thème de connexion" en "openstandia". Les autres thèmes ne seront pas modifiés.

themes.png

Modification du flux d'authentification

Modifiez le flux d'authentification depuis la console d'administration pour ajouter le module d'authentification SMS au processus d'authentification.

«Console de gestion» - «Authentification» - Écran de flux d'authentification «Navigateur»

console1.png

Copiez le flux d'authentification "Navigateur" (car le flux d'authentification par défaut "Navigateur" ne peut pas être modifié directement). Le nom du flux d'authentification est arbitraire.

console2.png

Copie du flux d'authentification "Openstandia Browser"

console3.png

Cliquez sur "Actions" dans "Openstandia Browser Forms" et cliquez sur "Add Execution".

console4.png

Sélectionnez le module créé cette fois. Le nom d'affichage ici est le nom défini dans getDisplayType de SMSAuthenticatorFactory.

console5.png

Ajout de "Twilio SMS Authentication" et déplacement de l'ordre d'exécution au-dessus de "OTP Form". "OTP Form" est réglé sur désactivé (DISABLED) (facultatif)

console6.png

Cliquez sur "Action" de "Twilio SMS Authentication" et cliquez sur "Paramètres". Les éléments d'écran définis dans getConfigProperties de SMSAuthenticatorFactory sont affichés ici.

console7.png

  • "API-KEY" définit l'API-KEY obtenue par Twilio.
  • Si vous avez besoin d'un proxy, définissez Proxy Enabled sur On et entrez les informations de proxy.
  • "Longueur du code SMS" est le nombre de chiffres du code de vérification à envoyer.

Revenez au flux d'authentification et cliquez sur l'onglet "Liaison". Remplacez le flux du navigateur par le "navigateur Openstandia" copié.

console8.png

Ceci termine les modifications de la console de gestion.

Contrôle de fonctionnement

Ajoutez des informations de numéro de téléphone aux attributs utilisateur pour vous connecter à l'avance. Faites correspondre la "Clé" de l'attribut du numéro de téléphone avec le nom de l'attribut dans le module d'authentification.

user_telnum.png

Connectez-vous à l'écran de gestion de compte (http: // localhost: 8080 / auth / realms / nom de domaine / compte)

Login.png

L'écran de saisie du code de vérification s'affiche.

verifyinput.png

Le code de vérification sera envoyé au numéro de téléphone saisi par SMS.

認証コード.png

Entrer le code de vérification

verify1.png

La connexion est terminée

verifyok.png

  • Ce qui suit est un écran d'erreur lorsque le mauvais code est entré. Le message d'erreur «Le code d'authentification ne correspond pas» est le message défini par setError of Response (Challenge).

verifyerror.png

C'est la fin du contrôle de fonctionnement.

finalement

J'ai personnalisé le SPI d'authentification et ajouté l'authentification par SMS au processus d'authentification. La personnalisation de Keycloak n'est pas limitée à l'authentification SPI, et la méthode de personnalisation pour tous les SPI est fondamentalement la même.

Tout simplement

  • Vérifiez le SPI qui correspond à la fonction à personnaliser. (Cette fois, authentification SPI)

  • Vérifiez les «implémentations» que la fonctionnalité que vous souhaitez personnaliser doit être. (Cette fois, authentificateur)

  • Implémentez la méthode fournie par ʻimplements l''interface cible.

Seulement ça.

Lors de la mise en œuvre de la troisième méthode, nous la mettrons en œuvre tout en comprenant le rôle de chaque méthode. (Parce que c'est le principal, cela prend le plus de temps, mais ...)

Une fois que vous aurez expérimenté la personnalisation d'un SPI, vous serez en mesure de l'implémenter en douceur, même si vous personnalisez un autre SPI à partir de maintenant. Veuillez essayer de personnaliser Keycloak: +1:

Matériel de référence

mark.png

Recommended Posts

Essayez d'ajouter l'authentification SMS (à l'aide de Twilio) au processus d'authentification Keycloak
Essayez d'ajouter du texte à une image avec Scala en utilisant la bibliothèque standard de Java