-
Notifications
You must be signed in to change notification settings - Fork 124
MTLS Extended Validation design #267
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
Open
DmitryMishchuk
wants to merge
3
commits into
keycloak:main
Choose a base branch
from
DmitryMishchuk:mtls_extension_design
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,208 @@ | ||
# MTLS Validation Extension (MTLS_Ext) | ||
|
||
* **Status**: Notes | ||
* **JIRA**: TBD | ||
|
||
|
||
## Motivation | ||
|
||
MTLS validation extension is designed to enable extension of standard SSL Certificate validation already present inside Keycloak (X509) enabling validation of additional fields present in different certificate types (example: QWAC), when MTLS | ||
support is | ||
enabled. | ||
|
||
QWAC is a sample of standard certificate extension that is occurring on OPEN BANKING Environment | ||
(link to [QWAC spec](https://www.etsi.org/deliver/etsi_ts/119400_119499/119495/01.03.01_60/ts_119495v010301p.pdf)). | ||
|
||
Introducing an extra introspection/validation SPI has such main benefits: | ||
|
||
* Support validation of additional SSL Certificate fields | ||
* Support for market specific OpenBanking implementations for example European PSD2 (QWAC) or Australian CDR (normative usage of existing fields) | ||
* Support custom (proprietary) certificate validation implementations | ||
|
||
## Implementation details | ||
We have to provide new Certificate validation SPI. | ||
This SPI may be implemented by a separate service (plugin), which deals with custom SSL Certificate processing. | ||
This plugin should be deployed inside the Keycloak and should handle all custom (proprietary) validation and parsing logic, so that Keycloak only interacts with it via SPI. | ||
|
||
### Affected classes | ||
- X509ClientAuthenticator.java (existing class bearing the basic SSL validation and storage logics) | ||
- MtlsExtendedValidationSpi.java (SPI meant to build validation plugins for different SSL Certificate types) | ||
- MtlsExtendedValidationProvider.java (provider bearing main methods) | ||
- MtlsExtendedValidationProviderFactory.java (provider initiating factory) | ||
- org.keycloak.provider.Spi (existing Spi register) | ||
- OIDCAdvancedConfigWrapper.java (existing config wrapper should be extended with additional properties) | ||
- OIDCClientRepresentation.java (existing client representation should be extended with additional properties) | ||
- OIDCConfigAttributes.java (existing config, should be extended) | ||
- OIDCConfigurationRepresentation.java (existing config representation, should be extended with additional properties) | ||
- DescriptionConverter.java (existing converter, should be extended) | ||
- admin-messages_en.properties (existing properties, should be extended with new descriptions for UI) | ||
- client-detail.html (existing htlm page, should be extended with new selectors to apply additional external mtls validation to a certain client and pick desired implementation) | ||
- clients.js (existing js services class, should be extended to get/store mtls validation related data from/to client properties) | ||
|
||
### X509ClientCertificateAuthenticator and UI implementation part | ||
- Admin UI section `Client/Advanced Settings` should be extended with a flag `Enable custom certificate validation` to be sure that additional validation should be turned on/off for | ||
particular client with possibility to pick corresponding implementation from a drop-down list. | ||
- Adding MtlsExtendedValidationSpi.class as SPI for plugin extension along with corresponding MtlsExtendedValidationProviderFactory class and MtlsExtendedValidationProvider class | ||
- Modification of X509ClientAuthenticator with calls to MtlsExtendedValidationSpi to introspect/validate the certificate if `custom validation is enabled` for current `client` | ||
|
||
### MtlsExtendedValidationSpi class | ||
Should extend Spi interface and implement corresponding methods as follows: | ||
```java | ||
package org.keycloak.mtls; | ||
|
||
import org.keycloak.provider.Provider; | ||
import org.keycloak.provider.ProviderFactory; | ||
import org.keycloak.provider.Spi; | ||
|
||
public class MtlsExtendedValidationSpi implements Spi { | ||
@Override | ||
public boolean isInternal() { | ||
return false; | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return "tls-client-extended-validation-impl"; | ||
} | ||
|
||
@Override | ||
public Class<? extends Provider> getProviderClass() { | ||
return MtlsExtendedValidationProvider.class; | ||
} | ||
|
||
@Override | ||
public Class<? extends ProviderFactory> getProviderFactoryClass() { | ||
return MtlsExtendedValidationProviderFactory.class; | ||
} | ||
} | ||
|
||
``` | ||
|
||
### MtlsExtendedValidationProvider class | ||
Should extend Provider interface and have following methods: | ||
- Method `parseAdditionalFields` must handle extraction and storage of additional fields from custom certificates into the AuthenticationFlowContext | ||
- Method `performAdditionalValidation` must handle all the logics concerning certificate validation | ||
```java | ||
package org.keycloak.mtls; | ||
|
||
import org.keycloak.provider.Provider; | ||
|
||
import java.security.cert.X509Certificate; | ||
import java.util.Map; | ||
|
||
public interface MtlsExtendedValidationProvider extends Provider { | ||
|
||
Map<String, String> parseAdditionalFields(X509Certificate[] certs); | ||
|
||
void performAdditionalValidation(X509Certificate[] certs); | ||
} | ||
``` | ||
|
||
Additionally, it may carry the following logics: | ||
- additional fields validation | ||
- roles validation for presence and syntax | ||
- online check for certificate validity at certificate issuer | ||
|
||
### Sample implementation | ||
Should contain the following: | ||
- SampleMtlsVerificationProviderImpl.java - implementing `MtlsExtendedValidationProvider` and carrying corresponding parsing and validation logics, should have `ID` parameter for easy navigation in Keycloak Admin UI and further search | ||
among other providers inside Keycloak | ||
- SampleMtlsVerificationProviderFactory.java - implementing `MtlsExtendedValidationProviderFactory` | ||
- org.keycloak.mtls.MtlsExtendedValidationProviderFactory - sould be located in `/resources/META-INF/services/` carrying ProviderFactory initialization | ||
- jboss-deployment-structure.xml - sould be located in `src/main/resources/META-INF/` | ||
|
||
#### Samples | ||
#####SampleMtlsValidationProviderImpl.java | ||
```java | ||
import org.jboss.logging.Logger; | ||
import org.keycloak.mtls.MtlsExtendedValidationProvider; | ||
|
||
import java.security.cert.X509Certificate; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
public class SampleMtlsValidationProviderImpl implements MtlsExtendedValidationProvider { | ||
static final String ID = "Sample External MTLS Verification Implementation"; // This ID is used in Keycloak Admin UI to pick the required implementation from the dropdown in Clients "Advanced Settings" Section | ||
// and in X509ClientAuthenticator.class to identify and pick provider corresponding to current client | ||
private static final Logger LOG = Logger.getLogger(MtlsExtendedValidationProvider.class); | ||
|
||
@Override | ||
public Map<String, String> parseAdditionalFields(X509Certificate[] certs) { | ||
LOG.info("Here we will parse additional fields from our Certificates"); | ||
HashMap<String, String> map = new HashMap<>(); | ||
map.put("Additional field name here","corresponding value for mentioned field"); | ||
return map; | ||
} | ||
|
||
@Override | ||
public void performAdditionalValidation(X509Certificate[] certs) { | ||
LOG.error("Here we will perform our custom validation of MTLS Certificates"); | ||
} | ||
|
||
@Override | ||
public void close() { | ||
|
||
} | ||
} | ||
``` | ||
#####SampleMtlsValidationProviderFactoryImpl.java | ||
```java | ||
import org.jboss.logging.Logger; | ||
import org.keycloak.Config; | ||
import org.keycloak.models.KeycloakSession; | ||
import org.keycloak.models.KeycloakSessionFactory; | ||
import org.keycloak.mtls.MtlsExtendedValidationProvider; | ||
import org.keycloak.mtls.MtlsExtendedValidationProviderFactory; | ||
|
||
public class SampleMtlsProviderFactoryImpl implements MtlsExtendedValidationProviderFactory { | ||
private static final Logger LOG = Logger.getLogger(MtlsExtendedValidationProviderFactory.class); | ||
|
||
@Override | ||
public MtlsExtendedValidationProvider create(KeycloakSession session) { | ||
LOG.error("MtlsProviderInitiated!!!"); | ||
return new SampleMtlsValidationProviderImpl(); | ||
} | ||
|
||
@Override | ||
public void init(Config.Scope config) { | ||
|
||
} | ||
|
||
@Override | ||
public void postInit(KeycloakSessionFactory factory) { | ||
|
||
} | ||
|
||
@Override | ||
public void close() { | ||
|
||
} | ||
|
||
@Override | ||
public String getId() { | ||
return SampleMtlsValidationProviderImpl.ID; | ||
} | ||
} | ||
``` | ||
|
||
#####jboss-deployment-structure.xml | ||
```xml | ||
<jboss-deployment-structure> | ||
<deployment> | ||
<dependencies> | ||
<module name="org.keycloak.keycloak-core" /> | ||
<module name="org.keycloak.keycloak-server-spi" /> | ||
<module name="org.keycloak.keycloak-server-spi-private" /> | ||
<module name="org.keycloak.keycloak-services" /> | ||
<module name="org.keycloak.keycloak-common" /> | ||
<module name="org.jboss.logging" /> | ||
</dependencies> | ||
</deployment> | ||
</jboss-deployment-structure> | ||
``` | ||
#####org.keycloak.mtls.MtlsExtendedValidationProviderFactory | ||
```text | ||
your.sample.packages.SampleMtlsProviderFactoryImpl | ||
``` | ||
|
||
Compiled JAR should be then deployed in `standalone/deployments` folder of your Keycloak instance. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.