Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initialize project #1

Merged
merged 13 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true

[{*.java,*.xml,*.tfl}]
indent_size = 4
indent_style = tab
max_line_length = 120
tab_width = 4

[*.yml]
indent_size = 2
indent_style = space
21 changes: 21 additions & 0 deletions .github/workflows/maven.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Maven CI

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
cache: maven
- name: Build with Maven
run: mvn -B package -f pom.xml
84 changes: 84 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
##############################
## Java
##############################
.mtj.tmp/
*.class
*.jar
*.war
*.ear
*.nar
hs_err_pid*

##############################
## Maven
##############################
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
pom.xml.bak
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
.mvn/wrapper/maven-wrapper.jar

##############################
## Gradle
##############################
bin/
build/
.gradle
.gradletasknamecache
gradle-app.setting
!gradle-wrapper.jar

##############################
## IntelliJ
##############################
out/
!.idea/
.idea/*
!.idea/fileTemplates
.idea_modules/
*.iml
*.ipr
*.iws

##############################
## Eclipse
##############################
.settings/
tmp/
.metadata
.classpath
.project
*.tmp
*.bak
*.swp
*~.nib
local.properties
.loadpath
.factorypath

##############################
## NetBeans
##############################
nbproject/private/
nbbuild/
dist/
nbdist/
nbactions.xml
nb-configuration.xml

##############################
## Visual Studio Code
##############################
.vscode/
.code-workspace

##############################
## OS X
##############################
.DS_Store
3 changes: 3 additions & 0 deletions .idea/fileTemplates/includes/Copyright.java

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions .idea/fileTemplates/internal/AnnotationType.java

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions .idea/fileTemplates/internal/Class.java

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions .idea/fileTemplates/internal/Enum.java

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions .idea/fileTemplates/internal/Interface.java

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions .idea/fileTemplates/internal/Record.java

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 43 additions & 0 deletions .run/Build keycloak 2fa email.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Build keycloak 2fa email" type="MavenRunConfiguration" factoryName="Maven">
<MavenSettings>
<option name="myGeneralSettings"/>
<option name="myRunnerSettings"/>
<option name="myRunnerParameters">
<MavenRunnerParameters>
<option name="cmdOptions"/>
<option name="profiles">
<set/>
</option>
<option name="goals">
<list>
<option value="clean"/>
<option value="package"/>
</list>
</option>
<option name="multimoduleDir"/>
<option name="pomFileName" value="pom.xml"/>
<option name="profilesMap">
<map/>
</option>
<option name="projectsCmdOptionValues">
<list/>
</option>
<option name="resolveToWorkspace" value="false"/>
<option name="workingDirPath" value="$PROJECT_DIR$"/>
</MavenRunnerParameters>
</option>
</MavenSettings>
<extension name="net.ashald.envfile">
<option name="IS_ENABLED" value="false"/>
<option name="IS_SUBST" value="false"/>
<option name="IS_PATH_MACRO_SUPPORTED" value="false"/>
<option name="IS_IGNORE_MISSING_FILES" value="false"/>
<option name="IS_ENABLE_EXPERIMENTAL_INTEGRATIONS" value="false"/>
<ENTRIES>
<ENTRY IS_ENABLED="true" PARSER="runconfig" IS_EXECUTABLE="false"/>
</ENTRIES>
</extension>
<method v="2"/>
</configuration>
</component>
15 changes: 15 additions & 0 deletions .run/Deploy local keycloak.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Deploy local keycloak" type="docker-deploy" factoryName="docker-compose.yml"
server-name="Docker">
<deployment type="docker-compose.yml">
<settings>
<option name="envFilePath" value=""/>
<option name="sourceFilePath" value="docker-compose.yml"/>
</settings>
</deployment>
<method v="2">
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Build keycloak 2fa email"
run_configuration_type="MavenRunConfiguration"/>
</method>
</configuration>
</component>
76 changes: 76 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Keycloak Email 2FA SPI

[![Maven CI](https://github.com/mt-ag/keycloak-2fa-email/actions/workflows/maven.yml/badge.svg)](https://github.com/mt-ag/keycloak-2fa-email/actions/workflows/maven.yml)

Keycloak SPI that adds an individual authenticator for two-factor authentication via email.

## Getting started

Build the project locally:

```shell
git clone https://github.com/mt-ag/keycloak-2fa-email
cd keycloak-2fa-email
mvn package
```

Copy the generated `.jar` file from the `target/` directory, into the `keycloak/providers/` directory.

## Setup

### SMTP Server

Connect Keycloak to an SMTP server in your realm's email settings.
See the [official Keycloak documentation](https://www.keycloak.org/docs/latest/server_admin/index.html#_email) for more
details on how to do so.

### Authentication Flows

The SPI adds a new authentication provider that can be used in browser-based Auth-flows.
First make a copy of the built-in browser flow.
Add the step `Email Verification Code` to the flow and set it to be conditional.
See:

<img alt="Auth flow example" src="docs/auth-flow.png">

There are three settings for the `Email Verification Code` step:

| Name | Description | Default |
|--------------|-------------------------------------------------|--------------------|
| Code length | Length of the generated code | `6` |
| Code Base | Used characters in the generated code | `1234567890ABCDEF` |
| Time-to-live | Time to live of the code to be valid in seconds | `300` |

### User requirements

A user hat to meet the following requirements to use the email 2FA provider:

- User needs an email address in their profile
- The email address must be verified

The `Email Verification Code` can be added to a conditional flow, so that is only used for specific users.

## Contributing

We are happy to receive pull request and issues.

### Development

First clone the repository and build the project:

```shell
git clone https://github.com/mt-ag/keycloak-2fa-email
cd keycloak-2fa-email
mvn package
```

To test the SPI, you can use the `docker-compose.yml` file in the root directory of the repository.
It starts a Keycloak instance with the SPI and a MailHog instance to capture all emails sent by Keycloak.

```shell
docker-compose up
```

After the first start you have to configure Keycloak to use `localhost:1025` as host and port for the SMTP server.
Then navigate your browser to `http://localhost:8025` to see all emails that have been sent by Keycloak.
To access the Keycloak admin console, use `http://localhost:8080` and log in with the credentials `admin` and `admin`.
32 changes: 32 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
version: '3'

services:
mailhog:
image: mailhog/mailhog:latest
ports:
- "1025:1025"
- "8025:8025"
networks:
keycloak:
aliases:
- mailhog

keycloak:
image: quay.io/keycloak/keycloak:23.0.0
ports:
- "8080:8080"
command: [ 'start-dev' ]
environment:
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin
volumes:
- type: bind
source: ./target/keycloak-2fa-email.jar
target: /opt/keycloak/providers/keycloak-2fa-email.jar
networks:
keycloak:
aliases:
- keycloak

networks:
keycloak:
Binary file added docs/auth-flow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
60 changes: 60 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.it-solutions</groupId>
<artifactId>keycloak-2fa-email</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>

<keycloak.version>23.0.0</keycloak.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-server-spi</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-server-spi-private</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-services</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<scope>provided</scope>
</dependency>
</dependencies>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-parent</artifactId>
<version>${keycloak.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<build>
<finalName>keycloak-2fa-email</finalName>
</build>

</project>
Loading
Loading