项目作者: cooper-lyt

项目描述 :
A Keycloak provider which phone and SMS
高级语言: Java
项目地址: git://github.com/cooper-lyt/keycloak-phone-provider.git
创建时间: 2020-10-29T06:38:15Z
项目社区:https://github.com/cooper-lyt/keycloak-phone-provider

开源协议:MIT License

下载


Keycloak (Quarkus 21.x.x) Phone Provider

Build Status
ci
ci

  • 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_uri params

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-regx rename to number-regex, and match regex at after canonicalize phone number
  • Fixed Bug #40 OTP Cookie bypass
  • Remove OTP setting Cookie Max Age and 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 SMS or setting Create OTP Credential in user registration ), Regardless of the user’s phone number
  • Cli param hour-maximum rename to target-hour-maximum
  • Add cli param source-hour-maximum

Migration:

  • Set cli param canonicalize-phone-numbers is “” or compatible is true , because in old user data phone number is not canonicalize.
  • Change number-regx to number-regex and 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:

If you want to build the project, simply run examples/docker-build.sh after cloning the repository.

  • keycloak-phone-provide
    main

  • keycloak-phone-provide.resources
    theme

  • keycloak-sms-provider-dummy
    test message will print to console.

    For sms service provider, choose one of:
    keycloak-sms-provider-aws-sns
    keycloak-sms-provider-totalvoice
    keycloak-sms-provider-twilio
    keycloak-sms-provider-cloopen
    keycloak-sms-provider-yunxin
    keycloak-sms-provider-aliyun
    keycloak-sms-provider-tencent

  • Local

    1. local keycloak installed: copy the target\providers to keycloak home directory
    2. kc.[sh|bat] build
    3. Start Keycloak.
  • Cli params

    1. kc.[sh|bat] start \
    2. --spi-phone-default-service=[dummy|aws|aliyun|cloopen| ...] # Which sms provider
    3. --spi-phone-default-token-expires-in=60 # sms expires ,default 60 second
    4. --spi-phone-default-source-hour-maximum=10 # How many send from ip address sms count in one hour, Zero is no limit. default 10
    5. --spi-phone-default-target-hour-maximum=3 # How many send to phone number sms count in one hour, Zero is no limit, default 3
    6. --spi-phone-default-[$realm-]duplicate-phone=false # allow one phone register multi user, default: false
    7. --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
    8. --spi-phone-default-[$realm-]valid-phone=true # valid phone number, default: true
    9. #whether to parse user-supplied phone numbers and put into canonical International E.163 format. _Required for proper duplicate phone number detection_
    10. --spi-phone-default-[$realm-]canonicalize-phone-numbers=E164 #[E164,INTERNATIONAL,NATIONAL,RFC3966], default: "" un-canonicalize;
    11. #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
    12. --spi-phone-default-[$realm-]phone-default-region=US #default: use realm setting's default Locate;
    13. #if compatible is true then search user will be use all format phone number
    14. --spi-phone-default-[$realm-]compatible=false #default: false
    15. #Prevent 2FA from always happening for a period of time
    16. --spi-phone-default-[$realm-]otp-expires=3600 #default: 60 * 60; 1 hour
    17. ... # 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.

  1. 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 Registration flow to Registration with phone flow through the menu button on the right of the registration flow

  • Replace Registration User Creation with Registration Phone User Creation

  • (Optional) Click on settings for Registration Phone User Creation to configure it

  • (Optional) To enable phone verification, click on Registration with phone registration Form >Add Phone validation if you want to verify phone.

  • (Optional) Read query parameter add to user attribute:
    Click on Registration with phone registration Form > Actions > Add execution on the Query Parameter Reader line
    Click on Registration with phone registration Form > Actions > configure add accept param name in to

  • (Optional) Hidden password field:
    Delete or disable Password Validation.

  • (Optional) if not any user profile:
    Delete or disable Profile 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 with phone

Registration URL:

  1. 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 Browser flow to Browser with phone flow
  • Replace Username Password Form with Phone Username Password Form
  • Click on the settings icon next to Phone Username Password Form to 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

Login By phone

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.

OTP

Only use phone login or get Access token use endpoints:

Under Authentication > Flows:

  • Copy the Direct Grant flow to Direct grant with phone flow
  • Click on Add step on the Provide Phone Number line
  • Click on Add step on the Provide Verification Code line
  • Delete or disable other
  • Set both of Provide Phone Number and Provide Verification Code to REQUIRED

Under Clients > $YOUR_CLIENT > Advanced > Authentication Flow Overrides
Bind Direct Grant Flow to Direct grant with phone

Setting

Either Phone/Otp or Username/Password :
Setting

Android client example

Everybody phone number( if not exists create user by phone number) get Access token use endpoints:

Under Authentication > Flows:

  • Copy the Direct Grant flow to Direct grant everybody with phone flow
  • Click on Actions > Add step on the Authentication Everybody By Phone line and move to first
  • Delete or disable other
  • Set Authentication Everybody By Phone to REQUIRED

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/token
    Content-Type: application/x-www-form-urlencoded
    grant_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 credentials flow to Reset credentials with phone flow
  • Click on Add step on the Rest Credential With Phone line
  • Click on Add step on the Send Rest Email If Not Phone line
  • Delete or disable other
  • set Send Rest Email If Not Phone to Conditional
  • Set both of Rest Credential With Phone and Reset Password to REQUIRED

Set Bind Reset credentials with phone to Reset credentials flow

Authentication setting

Conditional

Condition - phone provided

Required Action

  • Update Phone Number update user’s phone number on next login.
  • Configure OTP over SMS update 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!