-
-
Notifications
You must be signed in to change notification settings - Fork 662
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(auth): add a header authentification for reverse proxy
close #724
- Loading branch information
1 parent
eb330a9
commit b1fdcf4
Showing
9 changed files
with
317 additions
and
29 deletions.
There are no files selected for viewing
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
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
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,24 @@ | ||
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; | ||
|
||
@Data | ||
@ConfigurationProperties("akhq.security.header-auth") | ||
public class HeaderAuth { | ||
String userHeader; | ||
String groupsHeader; | ||
List<Users> users; | ||
|
||
@Data | ||
public static class Users { | ||
String username; | ||
List<String> groups = new ArrayList<>(); | ||
} | ||
} | ||
|
116 changes: 116 additions & 0 deletions
116
src/main/java/org/akhq/modules/HeaderAuthenticationFetcher.java
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,116 @@ | ||
package org.akhq.modules; | ||
|
||
import io.micronaut.context.annotation.Requires; | ||
import io.micronaut.core.async.publisher.Publishers; | ||
import io.micronaut.http.HttpRequest; | ||
import io.micronaut.security.authentication.Authentication; | ||
import io.micronaut.security.authentication.AuthenticationUserDetailsAdapter; | ||
import io.micronaut.security.authentication.Authenticator; | ||
import io.micronaut.security.authentication.UserDetails; | ||
import io.micronaut.security.filters.AuthenticationFetcher; | ||
import io.micronaut.security.token.config.TokenConfiguration; | ||
import io.reactivex.Flowable; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.akhq.configs.HeaderAuth; | ||
import org.akhq.utils.ClaimProvider; | ||
import org.reactivestreams.Publisher; | ||
|
||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.Optional; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
import javax.inject.Inject; | ||
import javax.inject.Singleton; | ||
|
||
@Requires(beans = HeaderAuth.class) | ||
@Singleton | ||
@Slf4j | ||
public class HeaderAuthenticationFetcher implements AuthenticationFetcher { | ||
@Inject | ||
HeaderAuth headerAuth; | ||
|
||
@Inject | ||
Authenticator authenticator; | ||
|
||
@Inject | ||
ClaimProvider claimProvider; | ||
|
||
@Inject | ||
TokenConfiguration configuration; | ||
|
||
@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.empty(); | ||
|
||
if (userHeaders.isEmpty()) { | ||
return Publishers.empty(); | ||
} | ||
|
||
return Flowable | ||
.fromCallable(() -> { | ||
List<String> strings = groupsMapper(userHeaders.get(), groupHeaders); | ||
|
||
if (strings.size() == 0) { | ||
return Optional.<ClaimProvider.AKHQClaimResponse>empty(); | ||
} | ||
|
||
ClaimProvider.AKHQClaimRequest claim = | ||
ClaimProvider.AKHQClaimRequest.builder() | ||
.providerType(ClaimProvider.ProviderType.HEADER) | ||
.providerName(null) | ||
.username(userHeaders.get()) | ||
.groups(strings) | ||
.build(); | ||
|
||
return Optional.of(claimProvider.generateClaim(claim)); | ||
|
||
}) | ||
.switchMap(t -> { | ||
if (t.isPresent()) { | ||
UserDetails userDetails = new UserDetails( | ||
userHeaders.get(), | ||
t.get().getRoles(), | ||
t.get().getAttributes() | ||
); | ||
|
||
return Flowable.just(new AuthenticationUserDetailsAdapter( | ||
userDetails, | ||
configuration.getRolesName(), | ||
configuration.getNameKey() | ||
)); | ||
} else { | ||
if (log.isDebugEnabled()) { | ||
log.debug("Could not authenticate {}", userHeaders.get()); | ||
} | ||
return Flowable.empty(); | ||
} | ||
}); | ||
} | ||
|
||
private List<String> groupsMapper(String user, Optional<String> groupHeaders) { | ||
if (headerAuth.getUsers() == null || headerAuth.getUsers().size() == 0) { | ||
return groupsSplit(groupHeaders) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
return headerAuth | ||
.getUsers() | ||
.stream() | ||
.filter(users -> users.getUsername().equals(user)) | ||
.flatMap(users -> Stream.concat( | ||
groupsSplit(groupHeaders), | ||
users.getGroups() != null ? users.getGroups().stream() : Stream.empty() | ||
)) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
private Stream<String> groupsSplit(Optional<String> groupHeaders) { | ||
return groupHeaders.stream().flatMap(s -> Arrays.stream(s.split(","))); | ||
} | ||
} |
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
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
Oops, something went wrong.