-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* chore: Initial commit * fix heading * hide Sverre's old package names
- Loading branch information
Showing
41 changed files
with
2,174 additions
and
1 deletion.
There are no files selected for viewing
Validating CODEOWNERS rules …
This file contains 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 @@ | ||
* @statnett/k3a |
This file contains 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,4 @@ | ||
{ | ||
"$schema": "https://docs.renovatebot.com/renovate-schema.json", | ||
"extends": ["github>statnett/renovate-config"], | ||
} |
This file contains 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,18 @@ | ||
--- | ||
name: CI | ||
on: | ||
pull_request: {} | ||
|
||
permissions: | ||
contents: read | ||
jobs: | ||
test: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: actions/setup-java@v3 | ||
with: | ||
java-version: '11' | ||
distribution: 'temurin' | ||
cache: maven | ||
- run: mvn --batch-mode verify |
This file contains 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,17 @@ | ||
--- | ||
name: Lint PR | ||
on: | ||
pull_request_target: | ||
types: | ||
- opened | ||
- edited | ||
- synchronize | ||
|
||
permissions: | ||
contents: read | ||
jobs: | ||
trigger: | ||
uses: statnett/github-workflows/.github/workflows/lint-pr.yaml@main | ||
permissions: | ||
pull-requests: write | ||
statuses: write |
This file contains 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,19 @@ | ||
--- | ||
name: Release Please | ||
on: | ||
push: | ||
branches: | ||
- main | ||
workflow_dispatch: | ||
|
||
permissions: | ||
contents: read | ||
jobs: | ||
trigger: | ||
uses: statnett/github-workflows/.github/workflows/release-please.yaml@main | ||
with: | ||
release-type: maven | ||
secrets: inherit | ||
permissions: | ||
contents: write | ||
pull-requests: write |
This file contains 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,21 @@ | ||
name: Publish package | ||
on: | ||
release: | ||
types: [created] | ||
jobs: | ||
publish: | ||
runs-on: ubuntu-latest | ||
permissions: | ||
contents: write | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: actions/setup-java@v3 | ||
with: | ||
java-version: '11' | ||
distribution: 'temurin' | ||
- name: Build package | ||
run: mvn --batch-mode verify | ||
- name: Push GitHub release artifact | ||
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v0.1.15 | ||
with: | ||
files: target/*.jar |
This file contains 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,20 @@ | ||
--- | ||
name: Scorecard supply-chain security | ||
on: | ||
branch_protection_rule: | ||
schedule: | ||
- cron: "20 7 * * 2" | ||
push: | ||
branches: | ||
- main | ||
|
||
permissions: | ||
contents: read | ||
jobs: | ||
trigger: | ||
uses: statnett/github-workflows/.github/workflows/scorecard.yaml@main | ||
permissions: | ||
security-events: write | ||
id-token: write | ||
contents: read | ||
actions: read |
This file contains 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,5 @@ | ||
.idea/ | ||
target | ||
*.iml | ||
.DS_Store | ||
*~ |
This file contains 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,5 @@ | ||
# Changelog | ||
|
||
## 1.0.0 (2020-10-23) | ||
|
||
* Initial, internal version. |
This file contains 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 |
---|---|---|
@@ -1,2 +1,138 @@ | ||
# k3a-ldap-authenticator | ||
A Kafka AuthenticateCallbackHandler that supports LDAP/Active Directory for username/password verification, including authorization based on group membership. | ||
|
||
This module contains: | ||
|
||
* A [Kafka | ||
`AuthenticateCallbackHandler`](src/main/java/io/statnett/k3a/authz/ldap/LdapAuthenticateCallbackHandler.java) | ||
that uses a directory (LDAP/Active Directory) to verify a username | ||
and a plain-text password. | ||
* A [Kafka | ||
`AclAuthorizer`](src/main/java/io/statnett/k3a/authz/ldap/LdapGroupAclAuthorizer.java) | ||
and | ||
[StandardAuthorizer](src/main/java/io/statnett/k3a/authz/ldap/LdapGroupStandardAuthorizer.java) | ||
that know about principals of type `Group`, and check them against | ||
LDAP/Active Directory group membership. The first is for | ||
installations that use ZooKeeper ACLs, the second for installations | ||
running without ZooKeepers. | ||
|
||
If you do not care about group membership, you only need to set up the | ||
first class. For group membership you need both, since the | ||
`AclAuthorizer`/`StandardAuthorizer` builds on data fetched by the | ||
`AuthenticateCallbackHandler`. | ||
|
||
## Misc. notes | ||
|
||
* Since all this is based on plain-text passwords, you will want to | ||
run it over SSL/TLS. | ||
* This is SASL_PLAIN, meaning that both the Kafka broker and the | ||
client application will get access to the user's password before | ||
passing it on to the directory server where the authentication is | ||
taking place. In many environments this is considered unacceptable: | ||
Look for something like OAUTH or SAML instead. | ||
* Although group membership is cached, there is no caching of the | ||
authentication result, but it is trivial to implement if needed. If | ||
you do, please do not use the plain-text password as part of the | ||
cache key, but pass it through a hashing function first. | ||
|
||
## Configuration | ||
|
||
Configuration is done using Kafka properties: Either | ||
`dot.separated.properties`, or `KAFKA_ENVIRONMENT_VARIABLES`. To use | ||
environment variables, capitalize every letter of the original | ||
property, replace any underscores with a double underscore, replace | ||
dots with underscores, and prefix with `KAFKA_`. | ||
|
||
### Kafka integration | ||
|
||
The `.jar`-file of this project must be made available on the Kafka | ||
Broker classpath, typically in `/usr/share/java/kafka/`. | ||
|
||
### Authenticator configuration | ||
|
||
You will need a binding and a listener for either `SASL_SSL` or | ||
`SASL_PLAINTEXT`. In the following we assume `SASL_SSL`, and a binding | ||
named `HUMAN`: | ||
|
||
```properties | ||
advertised.listeners=... ,HUMAN://broker:9094 | ||
listener.security.protocol.map=... ,HUMAN:SASL_SSL | ||
``` | ||
|
||
Tell Kafka to enable SASL, and to use our class to handle the protocol | ||
binding created above: | ||
|
||
```properties | ||
listener.name.human.plain.sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required ; | ||
listener.name.human.plain.sasl.server.callback.handler.class=io.statnett.k3a.authz.ldap.LdapAuthenticateCallbackHandler | ||
sasl.enabled.mechanisms=PLAIN | ||
``` | ||
|
||
The authenticator plug-in expects some configuration parameters, | ||
prefixed with `authz.ldap`, to tell it how to connect to and handle | ||
the LDAP Directory: | ||
|
||
```properties | ||
authz.ldap.host=openldap | ||
authz.ldap.port=389 | ||
authz.ldap.base.dn=dc=example,dc=com | ||
authz.ldap.username.to.dn.format=cn=%s,ou=People,dc=example,dc=com | ||
``` | ||
|
||
LDAPS (TLS) is assumed if the port is 636. For all other ports, | ||
plain-text LDAP is assumed. If using LDAPS with a self-signed | ||
certificate, the Broker JVM must be told to trust your | ||
certificates. How to do that is beyond the scope of this README. | ||
|
||
The final parameter, `ldap.username.to.dn.format`, specifies how the | ||
incoming username should be transformed to match whatever the | ||
directory expects as part of a bind operation. The `%s` combination | ||
will be replaced by a properly escaped version of what the user | ||
provided. On Active Directory this string should often be specified as | ||
just `%s`, since the directory authenticates using just the username | ||
without matching a full DN. | ||
|
||
### Group authorizer configuration | ||
|
||
If you want to enable ACLs which contain a `Group` principal type, you | ||
will need the above configuration, plus our `LdapGroupAclAuthorizer` | ||
(for ZooKeeper ACLs) or `LdapGroupStandardAuthorizer` for KRaft mode | ||
ACLs. | ||
|
||
Requirements for our group authorizer: | ||
|
||
* Authorization is done based on the automatically populated | ||
`memberOf` attribute that was introduced in draft [RFC | ||
2307bis](https://tools.ietf.org/id/draft-howard-rfc2307bis-01.txt). | ||
Although a draft RFC, this was adopted by Microsoft in Active | ||
Directory. Later, the same functionality has become available in | ||
other directories as well. | ||
* The Group authorizer does not use a distinct user for LDAP searches, | ||
but instead assumes that every user is allowed to search the entire | ||
LDAP tree to find itself. This is not the case everywhere. | ||
|
||
Tell Kafka to use this authorizer like this: | ||
|
||
```properties | ||
authorizer.class.name=io.statnett.k3a.authz.ldap.LdapGroupAclAuthorizer | ||
``` | ||
|
||
or this: | ||
|
||
```properties | ||
authorizer.class.name=io.statnett.k3a.authz.ldap.LdapGroupStandardAuthorizer | ||
``` | ||
|
||
The authorizer will perform a search in the entire LDAP tree to find | ||
the attributes of the authenticated user. The following attribute | ||
tells it how to map a username to a search filter: | ||
|
||
```properties | ||
authz.ldap.username.to.unique.search.format=uid=%s | ||
``` | ||
|
||
Group principals, for use in ACLs, must contain the full DN of the | ||
group: | ||
|
||
```text | ||
Group:cn=producers,ou=Groups,dc=example,dc=com | ||
``` |
This file contains 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,130 @@ | ||
<?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>io.statnett.k3a</groupId> | ||
<artifactId>k3a-ldap-authenticator</artifactId> | ||
<version>3.2.3-SNAPSHOT</version> | ||
<packaging>jar</packaging> | ||
|
||
<name>${project.groupId}:${project.artifactId}</name> | ||
<description>A Kafka AuthenticateCallbackHandler that supports LDAP/Active Directory for username/password verification, including authorization based on group membership.</description> | ||
<url>https://github.com/statnett/k3a-ldap-authenticator</url> | ||
|
||
<licenses> | ||
<license> | ||
<name>MIT License</name> | ||
<url>https://opensource.org/license/mit/</url> | ||
</license> | ||
</licenses> | ||
|
||
<scm> | ||
<connection>scm:git:git://github.com/statnett/k3a-ldap-authenticator.git</connection> | ||
<developerConnection>scm:git:ssh://github.com:statnett/k3a-ldap-authenticator.git</developerConnection> | ||
<url>https://github.com/statnett/k3a-ldap-authenticator/tree/main</url> | ||
</scm> | ||
|
||
<properties> | ||
<java.version>1.8</java.version> | ||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
<kafka.version>3.6.0</kafka.version> | ||
<kafka.scala.version>2.13</kafka.scala.version> | ||
</properties> | ||
|
||
<dependencies> | ||
|
||
<dependency> | ||
<groupId>org.apache.kafka</groupId> | ||
<artifactId>kafka-clients</artifactId> | ||
<version>${kafka.version}</version> | ||
<scope>provided</scope> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.apache.kafka</groupId> | ||
<artifactId>kafka_${kafka.scala.version}</artifactId> | ||
<version>${kafka.version}</version> | ||
<scope>provided</scope> | ||
</dependency> | ||
|
||
<!-- Required by Apache version of kafka-clients --> | ||
<dependency> | ||
<groupId>com.fasterxml.jackson.core</groupId> | ||
<artifactId>jackson-databind</artifactId> | ||
<version>2.15.3</version> | ||
<scope>provided</scope> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.slf4j</groupId> | ||
<artifactId>slf4j-jdk14</artifactId> | ||
<version>1.7.36</version> | ||
<scope>test</scope> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>no.shhsoft</groupId> | ||
<artifactId>k3a-embedded</artifactId> | ||
<version>0.5.0+${kafka.version}</version> | ||
<scope>test</scope> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>com.unboundid</groupId> | ||
<artifactId>unboundid-ldapsdk</artifactId> | ||
<version>6.0.10</version> | ||
<scope>test</scope> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.zapodot</groupId> | ||
<artifactId>embedded-ldap-junit</artifactId> | ||
<version>0.9.0</version> | ||
<scope>test</scope> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.junit.jupiter</groupId> | ||
<artifactId>junit-jupiter-engine</artifactId> | ||
<version>5.10.1</version> | ||
<scope>test</scope> | ||
</dependency> | ||
|
||
</dependencies> | ||
|
||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<version>3.11.0</version> | ||
<configuration> | ||
<source>${java.version}</source> | ||
<target>${java.version}</target> | ||
<encoding>UTF-8</encoding> | ||
</configuration> | ||
</plugin> | ||
|
||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-surefire-plugin</artifactId> | ||
<version>3.2.2</version> | ||
</plugin> | ||
|
||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-failsafe-plugin</artifactId> | ||
<version>3.2.2</version> | ||
<executions> | ||
<execution> | ||
<goals> | ||
<goal>integration-test</goal> | ||
<goal>verify</goal> | ||
</goals> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
</project> |
Oops, something went wrong.