Skip to content

Commit

Permalink
feat(auth): make group separator in header authentication customizable (
Browse files Browse the repository at this point in the history
#792)

* allow to run without header authentication
* customizable group separator for header authentication

relate to #724
  • Loading branch information
piotrp authored and tchiotludo committed Oct 24, 2021
1 parent 9894d0b commit b90af00
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 15 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -625,8 +625,9 @@ akhq:
# Header configuration (reverse proxy)
header-auth:
user-header: x-akhq-user # mandatory (the header name that will contain username)
groups-header: x-akhq-group # optional (the header name that will contains groups separated by coma `,`)
users: # optional, the users list allow, if empty we only rely on `groups-header`
groups-header: x-akhq-group # optional (the header name that will contain groups separated by groups-header-separator)
groups-header-separator: , # optional (separator, defaults to ',')
users: # optional, the users list to allow, if empty we only rely on `groups-header`
- username: header-user # username matching the `user-header` value
groups: # list of group for current users
- topic-reader
Expand All @@ -636,8 +637,9 @@ akhq:
```
* The `user-header` is mandatory in order to map the user with `users` list or to display the user on the ui if no `users` is provided.
* The `groups-header` is optional and can be used in order to inject a list of groups (separated by `,`) for all the users. This list will be merged with `groups` for the current users.
* The `users` is a list of users allowed.
* The `groups-header` is optional and can be used in order to inject a list of groups for all the users. This list will be merged with `groups` for the current users.
* The `groups-header-separator` is optional and can be used to customize group separator used when parsing `groups-header` header, defaults to `,`.
* The `users` is a list of allowed users.

### External roles and attributes mapping

Expand Down
5 changes: 3 additions & 2 deletions application.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,9 @@ akhq:
# Header configuration (reverse proxy)
header-auth:
user-header: x-akhq-user # mandatory (the header name that will contain username)
groups-header: x-akhq-group # optional (the header name that will contains groups separated by coma `,`)
users: # optional, the users list allow, if empty we only rely on `groups-header`
groups-header: x-akhq-group # optional (the header name that will contain groups separated by groups-header-separator)
groups-header-separator: , # optional (separator, defaults to ',')
users: # optional, the users list to allow, if empty we only rely on `groups-header`
- username: header-user # username matching the `user-header` value
groups: # list of group for current users
- topic-reader
Expand Down
4 changes: 1 addition & 3 deletions src/main/java/org/akhq/configs/HeaderAuth.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package org.akhq.configs;

import io.micronaut.context.annotation.ConfigurationProperties;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -13,6 +11,7 @@
public class HeaderAuth {
String userHeader;
String groupsHeader;
String groupsHeaderSeparator = ",";
List<Users> users;

@Data
Expand All @@ -21,4 +20,3 @@ public static class Users {
List<String> groups = new ArrayList<>();
}
}

15 changes: 9 additions & 6 deletions src/main/java/org/akhq/modules/HeaderAuthenticationFetcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,18 @@ public class HeaderAuthenticationFetcher implements AuthenticationFetcher {

@Override
public Publisher<Authentication> fetchAuthentication(HttpRequest<?> request) {
Optional<String> userHeaders = request.getHeaders()
.get(headerAuth.getUserHeader(), String.class);

Optional<String> groupHeaders = headerAuth.getGroupsHeader() != null ?
request.getHeaders().get(headerAuth.getGroupsHeader(), String.class) :
Optional<String> userHeaders = headerAuth.getUserHeader() != null ?
request.getHeaders().get(headerAuth.getUserHeader(), String.class) :
Optional.empty();

if (userHeaders.isEmpty()) {
return Publishers.empty();
}

Optional<String> groupHeaders = headerAuth.getGroupsHeader() != null ?
request.getHeaders().get(headerAuth.getGroupsHeader(), String.class) :
Optional.empty();

return Flowable
.fromCallable(() -> {
List<String> strings = groupsMapper(userHeaders.get(), groupHeaders);
Expand Down Expand Up @@ -111,6 +112,8 @@ private List<String> groupsMapper(String user, Optional<String> groupHeaders) {
}

private Stream<String> groupsSplit(Optional<String> groupHeaders) {
return groupHeaders.stream().flatMap(s -> Arrays.stream(s.split(",")));
return groupHeaders
.stream()
.flatMap(s -> Arrays.stream(s.split(headerAuth.getGroupsHeaderSeparator())));
}
}

0 comments on commit b90af00

Please sign in to comment.