Send verification code via e-mail after keycloak login.

huangapple go评论81阅读模式
英文:

Send verification code via e-mail after keycloak login

问题

是的,可以通过电子邮件或短信添加验证码以增加额外的安全层。

在我这种情况下,我想在React登录页面中使用Keycloak 21。用户输入用户名和密码后,还应提示输入通过电子邮件发送的验证码。

我尝试过这样做:

  1. 创建Realm:admin_console_realm

  2. 添加客户端:admin_console

  3. 创建用户:test

使用Postman,我尝试创建一个请求(类似于React SPA应用)来生成令牌:

POST: http://123.123.123.123:8080/realms/admin_console_realm/protocol/openid-connect/token?client_id=admin_console_client&grant_type=password

我收到响应:

{
    "access_token": "eyJhb....X8N8ulVbQ",
    "expires_in": 300,
    "refresh_expires_in": 1800,
    "refresh_token": "eyJhbGc....Q",
    "token_type": "Bearer",
    "not-before-policy": 0,
    "session_state": "5595860d-35d8-4fe1-9f6f-147c38255172",
    "scope": "email profile"
}

在Keycloak 21中,发送用户名和密码,然后使用通过电子邮件接收的确认码(OTP码)的正确方式是什么?

英文:

Is it possible to add verification code using e-mail or SMS in order to add additional security layer?

In my case I want to use Keycloak 21 with React login page. After user enters his username and password he should be prompted also to enter secret code delivered by e-mail.

I tried this:

1. Create Realm: admin_console_realm

Send verification code via e-mail after keycloak login.

2. Add client: admin_console

Send verification code via e-mail after keycloak login.

Send verification code via e-mail after keycloak login.

Send verification code via e-mail after keycloak login.

3. Create user: test

Send verification code via e-mail after keycloak login.

With Postman I tried to create a request(like a React SPA app) to generate token:

POST: http://123.123.123.123:8080/realms/admin_console_realm/protocol/openid-connect/token?client_id=admin_console_client&grant_type=password

I get response:

{
    "access_token": "eyJhb....X8N8ulVbQ",
    "expires_in": 300,
    "refresh_expires_in": 1800,
    "refresh_token": "eyJhbGc....Q",
    "token_type": "Bearer",
    "not-before-policy": 0,
    "session_state": "5595860d-35d8-4fe1-9f6f-147c38255172",
    "scope": "email profile"
}

What should be the proper way to send a username and password and then to use confirmation code (OTP code) received by e-mail for Keycloak 21?

答案1

得分: 1

在管理员控制台中,选择您要在Realm设置->登录下启用此选项的领域后,您可以选择在初始登录后要求用户验证其电子邮件的选项。如果您选中此选项,用户将需要验证其电子邮件才能继续进行身份验证。

请确保在同一Realm设置视图中的电子邮件选项卡中配置SMTP设置,以确保流程按预期工作。

英文:

In the admin console after selecting the realm for which you want to enable this under Realm Settings -> Login - you have an option to make the user verify their email after initial login. If you check this users will be required to verify their email to proceed with authentication.

Make sure to configure the SMTP settings as part of the Email tab in the same Realm Settings view in order for the flow to work as expected.

答案2

得分: 1

以下是翻译好的部分:

是的,可以使用Keycloak添加额外的安全层,通过电子邮件(或短信)发送验证码,可以使用一次性密码(OTP)策略来实现。

以下是您需要执行的一般步骤:

  1. 实现Keycloak SPI(服务提供程序接口): 要自定义Keycloak以通过电子邮件/短信发送OTP,您需要创建一个自定义SPI。Keycloak SPI允许您为Keycloak的某些方面提供自定义实现。

  2. 注册您的自定义SPI: 一旦您实现了自定义SPI,您需要注册它。您可以在standalone.xml、standalone-ha.xml或domain.xml文件中执行此操作,具体取决于您的操作模式。

  3. 启用和配置OTP策略: 在Keycloak管理控制台中,导航到Realm设置,然后转到Authentication选项卡。您应该能够为您的Realm配置OTP策略。

不幸的是,Keycloak不会在开箱即用时提供电子邮件/短信功能,您需要自己开发该部分(或使用现有的服务/库来执行此操作)。

一些注意事项:

  • 用于发送电子邮件的可以使用Java Mail API或任何其他电子邮件发送服务/库。用于发送短信,您需要使用Twilio或Nexmo等服务。

  • OTP应该是一个短的、随机生成的数字或字母数字字符串,发送给用户并存储在用户的会话或某个临时位置(之后清理),以便当用户输入OTP时,您可以验证它。

对于React部分,在用户输入用户名和密码后,您将重定向他们到一个新页面(或显示一个模态/对话框)来输入OTP。然后,OTP将发送到Keycloak服务器进行验证,如果有效,用户将成功进行身份验证。

首先,创建一个具有以下结构的Maven项目:

src
 └ main
     └ java
         └ com
             └ mycompany
                 └ keycloak
                     └ MyCustomProvider.java
                     └ MyCustomProviderFactory.java
pom.xml

以下是您的**MyCustomProvider.java**可能看起来像的内容:

package com.example.keycloak;

import org.keycloak.provider.Provider;

public class MyCustomProvider implements Provider {
    @Override
    public void close() {
        // 您的清理代码在这里
    }

    public void sendOTP(String email, String otp) {
        // 您的发送电子邮件代码在这里
    }
}

这是**MyCustomProviderFactory.java**:

package com.mycompany.keycloak;

import org.keycloak.Config;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.provider.ProviderFactory;

public class MyCustomProviderFactory implements ProviderFactory<MyCustomProvider> {
    @Override
    public MyCustomProvider create(KeycloakSession session) {
        return new MyCustomProvider();
    }

    @Override
    public void init(Config.Scope config) {
        // 初始化代码在这里
    }

    @Override
    public void postInit(KeycloakSessionFactory factory) {
        // 后期初始化代码在这里
    }

    @Override
    public void close() {
        // 清理代码在这里
    }

    @Override
    public String getId() {
        return "myCustomProvider";
    }
}

在**pom.xml**文件中,请确保包含Keycloak依赖项:

<dependencies>
    <dependency>
        <groupId>org.keycloak</groupId>
        <artifactId>keycloak-core</artifactId>
        <version>${keycloak.version}</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.keycloak</groupId>
        <artifactId>keycloak-server-spi</artifactId>
        <version>${keycloak.version}</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

一旦您实现了自定义提供程序和工厂,您需要在Keycloak中注册它。通过在**META-INF目录中添加一个keycloak-server.json**文件来执行此操作:

{
    "providers": [
        "classpath:${project.build.finalName}.jar"
    ],
    "spi": {
        "myCustomSpi": {
            "provider": "myCustomProvider",
            "enabled": true
        }
    }
}

请记住用您实际使用的SPI和提供程序ID替换**"myCustomSpi""myCustomProvider"**。

最后,要在Keycloak中注册您的SPI,您需要将其添加到**standalone.xmlstandalone-ha.xmldomain.xml**文件中:

<spi name="myCustomSpi">
    <provider name="myCustomProvider" enabled="true">
        <properties>
            <!-- 在这里添加您的SPI需要的任何属性 -->
        </properties>
    </provider>
</spi>

这只是一个非常基本的示例。在您的实际实现中,您需要实现代码以通过电子邮件或短信发送OTP、处理会话、验证OTP等等。此外,请注意,根据您想要执行的操作,Keycloak SPI可以非常复杂。我建议阅读Keycloak SPI文档

英文:

Yes, it's possible to add an additional security layer with Keycloak, sending a verification code via email (or SMS), which can be done using an OTP (One Time Password) policy.

Here are the general steps you would need to take:

  1. Implement a Keycloak SPI (Service Provider Interface): To customize
    Keycloak to send the OTP via email/SMS, you need to create a custom
    SPI. Keycloak SPIs allow you to provide custom implementations for
    certain aspects of Keycloak.
  2. Register Your Custom SPI: Once your custom SPI is implemented,
    you'll need to register it. You can do this in the standalone.xml,
    standalone-ha.xml, or domain.xml file, depending on your mode of
    operation.
  3. Enable and Configure the OTP Policy: In the Keycloak Admin Console,
    navigate to the Realm settings, then go to the Authentication tab.
    You should be able to configure an OTP policy for your realm.

Unfortunately, Keycloak doesn't provide the email/SMS functionality out of the box, and you'll need to develop that part yourself (or use an existing service/library to do that).

A couple of notes:

  • For sending emails, you can use Java Mail API or any other email
    sending service/library. For sending SMS, you'll need to use a
    service like Twilio or Nexmo.

  • The OTP should be a short, randomly generated number or alphanumeric
    string that is sent to the user and also stored in the user's session
    or some temporary location (that you clean up afterwards), so that
    when the user enters the OTP, you can validate it.

For the React part, after the user enters their username and password, you would redirect them to a new page (or show a modal/dialog) to enter the OTP. The OTP would then be sent to the Keycloak server for validation, and if valid, the user would be successfully authenticated.

First, create a Maven project with the following structure:

src
 └ main
     └ java
         └ com
             └ mycompany
                 └ keycloak
                     └ MyCustomProvider.java
                     └ MyCustomProviderFactory.java
pom.xml

Here is what your MyCustomProvider.java might look like:


    package com.example.keycloak;
    
    import org.keycloak.provider.Provider;
    
    public class MyCustomProvider implements Provider {
        @Override
        public void close() {
            // Your cleanup code here
        }
    
        public void sendOTP(String email, String otp) {
            // Your email sending code here
        }
    }

And here is MyCustomProviderFactory.java:


    package com.mycompany.keycloak;
    
    import org.keycloak.Config;
    import org.keycloak.models.KeycloakSession;
    import org.keycloak.models.KeycloakSessionFactory;
    import org.keycloak.provider.ProviderConfigProperty;
    import org.keycloak.provider.ProviderFactory;
    
    public class MyCustomProviderFactory implements ProviderFactory&lt;MyCustomProvider&gt; {
        @Override
        public MyCustomProvider create(KeycloakSession session) {
            return new MyCustomProvider();
        }
    
        @Override
        public void init(Config.Scope config) {
            // Initialization code here
        }
    
        @Override
        public void postInit(KeycloakSessionFactory factory) {
            // Post-initialization code here
        }
    
        @Override
        public void close() {
            // Cleanup code here
        }
    
        @Override
        public String getId() {
            return &quot;myCustomProvider&quot;;
        }
    }

In the pom.xml file, make sure to include Keycloak dependencies:


    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.keycloak&lt;/groupId&gt;
            &lt;artifactId&gt;keycloak-core&lt;/artifactId&gt;
            &lt;version&gt;${keycloak.version}&lt;/version&gt;
            &lt;scope&gt;provided&lt;/scope&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.keycloak&lt;/groupId&gt;
            &lt;artifactId&gt;keycloak-server-spi&lt;/artifactId&gt;
            &lt;version&gt;${keycloak.version}&lt;/version&gt;
            &lt;scope&gt;provided&lt;/scope&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;

Once you have implemented your custom provider and factory, you need to register it with Keycloak. You do this by adding a keycloak-server.json file in your META-INF directory:


    {
        &quot;providers&quot;: [
            &quot;classpath:${project.build.finalName}.jar&quot;
        ],
        &quot;spi&quot;: {
            &quot;myCustomSpi&quot;: {
                &quot;provider&quot;: &quot;myCustomProvider&quot;,
                &quot;enabled&quot;: true
            }
        }
    }

Remember to replace "myCustomSpi" and "myCustomProvider" with the SPI and provider IDs that you're using.

Finally, to register your SPI with Keycloak, you add it to the standalone.xml, standalone-ha.xml, or domain.xml file:


    &lt;spi name=&quot;myCustomSpi&quot;&gt;
        &lt;provider name=&quot;myCustomProvider&quot; enabled=&quot;true&quot;&gt;
            &lt;properties&gt;
                &lt;!-- Add any properties your SPI needs here --&gt;
            &lt;/properties&gt;
        &lt;/provider&gt;
    &lt;/spi&gt;

This is just a very basic example. In your actual implementation, you will need to implement the code to send the OTP via email or SMS, handle sessions, validate OTPs, etc. Also, note that Keycloak SPIs can be quite complex, depending on what you want to do. I recommend reading the Keycloak documentation on SPIs

huangapple
  • 本文由 发表于 2023年5月14日 01:19:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76244039.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定