keycloak-phone-provider
- Phone support like e-mail
- One Time Password (OTP) by phone
- Login by phone
- Register with phone
- Authentication by phone
- Reset password by phone
sms voice phone one key login
With this provider you can enforce authentication policies based on a verification token sent to users' mobile phones. Currently, there are implementations for:
- Aliyun
- AWS SNS
- Cloopen
- Tencent
- TotalVoice
- Twilio,
- YunTongXun SMS
More services can be added with ease due to the modularity of the code. In fact, nothing would stop you from implementing a sender of TTS calls or WhatsApp messages.
This is what you can do for now:
- Check ownership of a phone number (Forms and Rest API)
- Use SMS as second factor in 2FA method (Browser flow)
- Login by phone (Browser flow)
- Reset Password by phone
- Authentication by phone (Rest API)
- Authenticate everybody by phone, auto create user on Grant (Rest API)
- Register with phone
- Register only phone (username is phone number)
- Register add user attribute with
redirect_uriparams
Features
New in Version 2.3.3
- Add
Condition - phone provided#46
New in Version 2.3.2
- fix phone login form display error!
New in Version 2.3.1
- Canonicalize phone numbers using Google's libphonenumbers
- Valid phone number using Google's libphonenumbers
- Cli param
number-regxrename tonumber-regex, and match regex at after canonicalize phone number - Fixed Bug #40 OTP Cookie bypass
- Remove OTP setting
Cookie Max Ageand add cli param otp-expires - Refactor OTP , only use Credential's phone number (The certificate's phone number comes from Required action
Configure OTP over SMSor settingCreate OTP Credentialin user registration ), Regardless of the user's phone number - Cli param
hour-maximumrename totarget-hour-maximum - Add cli param
source-hour-maximum
Migration:
- Set cli param
canonicalize-phone-numbersis "" orcompatibleis true , because in old user data phone number is not canonicalize. - Change
number-regxtonumber-regexand change regex match after canonicalize phone number
New in Version 2.2.2
- fix phone number as username bug #24
Compatibility
This was initially developed using Quarkus Keycloak as baseline. Wildfily keycloak is not supported anymore and I did not test user storage beyond Kerberos or LDAP. I may try to help you but I cannot guarantee.
Usage
Installing:
- Docker
- docker image is coopersoft/keycloak:21.0.2_phone-2.3.3
- for examples docker-compose.yml
- run as
docker-compose up, docker-compose is required!
If you want to build the project, simply run examples/docker-build.sh after cloning the repository.
keycloak-phone-provide
mainkeycloak-phone-provide.resources
themekeycloak-sms-provider-dummy
test message will print to console.For sms service provider, choose one of:
keycloak-sms-provider-aws-snskeycloak-sms-provider-totalvoicekeycloak-sms-provider-twiliokeycloak-sms-provider-cloopenkeycloak-sms-provider-yunxinkeycloak-sms-provider-aliyunkeycloak-sms-provider-tencent
Local
- local keycloak installed: copy the
target\providersto keycloak home directory - kc.[sh|bat] build
- Start Keycloak.
- local keycloak installed: copy the
Cli params
kc.[sh|bat] start \ --spi-phone-default-service=[dummy|aws|aliyun|cloopen| ...] # Which sms provider --spi-phone-default-token-expires-in=60 # sms expires ,default 60 second --spi-phone-default-source-hour-maximum=10 # How many send from ip address sms count in one hour, Zero is no limit. default 10 --spi-phone-default-target-hour-maximum=3 # How many send to phone number sms count in one hour, Zero is no limit, default 3 --spi-phone-default-[$realm-]duplicate-phone=false # allow one phone register multi user, default: false --spi-phone-default-[$realm-]default-number-regex=^\+?\d+$ #Notice: will match after canonicalize number. eg: INTERNATIONAL: +41 44 668 18 00 , NATIONAL: 044 668 18 00 , E164: +41446681800 --spi-phone-default-[$realm-]valid-phone=true # valid phone number, default: true #whether to parse user-supplied phone numbers and put into canonical International E.163 format. _Required for proper duplicate phone number detection_ --spi-phone-default-[$realm-]canonicalize-phone-numbers=E164 #[E164,INTERNATIONAL,NATIONAL,RFC3966], default: "" un-canonicalize; #a default region to be used when parsing user-supplied phone numbers. Lookup codes at https://www.unicode.org/cldr/cldr-aux/charts/30/supplemental/territory_information.html --spi-phone-default-[$realm-]phone-default-region=US #default: use realm setting's default Locate; #if compatible is true then search user will be use all format phone number --spi-phone-default-[$realm-]compatible=false #default: false #Prevent 2FA from always happening for a period of time --spi-phone-default-[$realm-]otp-expires=3600 #default: 60 * 60; 1 hour ... # provider param refer provider`s readme.md
Theme
You will need to change the realm login theme to phone.
You can create a customized theme base on phone.
parent=phone
Phone registration support
Two user attributes are going to be used by this provider: phoneNumberVerified (bool) and phoneNumber (str). Multiple
users can have the same phoneNumber, but only one of them will have phoneNumberVerified = true at the end of a
verification process. This accommodates the use case of pre-paid numbers that get recycled if inactive for too much time.
Under Authentication > Flows:
Copy the
Registrationflow toRegistration with phoneflow through the menu button on the right of theregistrationflowReplace
Registration User CreationwithRegistration Phone User Creation(Optional) Click on settings for
Registration Phone User Creationto configure it(Optional) To enable phone verification, click on
Registration with phone registration Form>AddPhone validationif you want to verify phone.(Optional) Read query parameter add to user attribute:
Click onRegistration with phone registration Form>Actions>Add executionon theQuery Parameter Readerline
Click onRegistration with phone registration Form>Actions>configureadd accept param name in to(Optional) Hidden password field:
Delete or disablePassword Validation.(Optional) if not any user profile:
Delete or disableProfile Validation
Set all added items as Required.
On the Authentication page, bind Registration with phone to Registration flow and select it to be Required.
Under Realm Settings > Themes
Set Login Theme to phone
Tip:
If Realm parameter Email as username is true, then config Phone number as username and hide email is invalid!
If parameter duplicate-phone is true then Phone number as username is invalid!

Registration URL:
http://<domain>/realms/<realm name>/protocol/openid-connect/registrations?client_id=<client id>&response_type=code&scope=openid%20email&redirect_uri=<redirect_uri>
Login by phone
Under Authentication > Flows:
- Copy the
Browserflow toBrowser with phoneflow - Replace
Username Password FormwithPhone Username Password Form - Click on the settings icon next to
Phone Username Password Formto configure.
Under Realm Settings > Themes
Set Login Theme as phone
Set Bind Browser with phone to Browser flow
On the Authentication page, bind Browser with phone to Browser flow

2FA by Phone OTP
Phone OTP uses OTP Credential's phone number,Different from the user's phone number, Credential's phone number come from required actions Configure OTP over SMS, Unless the Create OTP Credential is enabled on user registration flow.
On Authentication page, copy the browser flow and replace OTP with OTP Over SMS . Don't forget to bind this flow copy as the de facto browser flow.
Finally, Enable the required actions Configure OTP over SMS in the Required Actions tab.

Only use phone login or get Access token use endpoints:
Under Authentication > Flows:
- Copy the
Direct Grantflow toDirect grant with phoneflow - Click on
Add stepon theProvide Phone Numberline - Click on
Add stepon theProvide Verification Codeline - Delete or disable other
- Set both of
Provide Phone NumberandProvide Verification CodetoREQUIRED
Under Clients > $YOUR_CLIENT > Advanced > Authentication Flow Overrides
Bind Direct Grant Flow to Direct grant with phone

Either Phone/Otp or Username/Password :

Everybody phone number( if not exists create user by phone number) get Access token use endpoints:
Under Authentication > Flows:
- Copy the
Direct Grantflow toDirect grant everybody with phoneflow - Click on
Actions>Add stepon theAuthentication Everybody By Phoneline and move to first - Delete or disable other
- Set
Authentication Everybody By PhonetoREQUIRED
Under Clients > $YOUR_CLIENT > Advanced > Authentication Flow Overrides
Set Direct Grant Flow to Direct grant everybody with phone
About the API endpoints:
You'll get 2 extra endpoints that are useful to do the verification from a custom application.
GET /realms/{realmName}/sms/verification-code?phoneNumber=+5534990001234(To request a number verification. No auth required.)POST /realms/{realmName}/sms/verification-code?phoneNumber=+5534990001234&code=123456(To verify the process. User must be authenticated.)
You'll get 2 extra endpoints that are useful to do the access token from a custom application.
GET /realms/{realmName}/sms/authentication-code?phoneNumber=+5534990001234(To request a number verification. No auth required.)POST /realms/{realmName}/protocol/openid-connect/tokenContent-Type: application/x-www-form-urlencodedgrant_type=password&phone_number=$PHONE_NUMBER&code=$VERIFICATION_CODE&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRECT
And then use Verification Code authentication flow with the code to obtain an access code.
Reset Credentials
Under Authentication > Flows:
- Copy the
Reset credentialsflow toReset credentials with phoneflow - Click on
Add stepon theRest Credential With Phoneline - Click on
Add stepon theSend Rest Email If Not Phoneline - Delete or disable other
- set
Send Rest Email If Not PhonetoConditional - Set both of
Rest Credential With PhoneandReset PasswordtoREQUIRED
Set Bind Reset credentials with phone to Reset credentials flow

Conditional
Condition - phone provided
Required Action
Update Phone Numberupdate user's phone number on next login.Configure OTP over SMSupdate OTP Credential's phone number on next login.
Phone one key login Testing , coming soon!
Thanks
Some code written is based on existing ones in these two projects: keycloak-sms-provider and keycloak-phone-authenticator. Certainly I would have many problems coding all those providers blindly. Thank you!
