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

Fraschbi/rbac listener config #6

Merged
merged 4 commits into from
Aug 21, 2020
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
13 changes: 12 additions & 1 deletion README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
:hivemq-blog-tools: http://www.hivemq.com/mqtt-toolbox
:maven-documentation-profile-link: http://maven.apache.org/guides/introduction/introduction-to-profiles.html
:hivemq-support: http://www.hivemq.com/support/
:hivemq-listener: https://www.hivemq.com/docs/hivemq/4.4/user-guide/listeners.html#tcp-listener

== HiveMQ File Role based Access Control Extension

*Extension Type*: Security

*Version*: 4.0.0
*Version*: 4.4.0

*License*: Apache License 2.0

Expand All @@ -31,6 +32,7 @@ The extension provides fine grained control on a topic level to limit clients to
* Runtime reload for Credentials and Roles
* Support for Hashed or Plain-text passwords
* Tooling to generate salted password hashes
* Option to define a set of listeners the extension is used for

=== Installation

Expand Down Expand Up @@ -210,6 +212,12 @@ The credentials configuration includes the following settings.
<!-- Reload interval for credentials in seconds -->
<credentials-reload-interval>60</credentials-reload-interval>

<!-- Optional list of names of listeners this extension is used for
<listener-names>
<listener-name>my-listener</listener-name>
<listener-name>my-listener-2</listener-name>
</listener-names> -->

<!-- If the credentials file is using HASHED or PLAIN passwords -->
<password-type>HASHED</password-type>

Expand All @@ -221,9 +229,12 @@ The credentials configuration includes the following settings.
|===
|Configuration |Default |Description
|`credentials-reload-interval` |`60` |Regular interval in seconds, in which the `credentials.xml` configuration file is checked for changes and reloaded.
|`listener-names` |`null` |List of names of listeners, this extension will be used for. See {hivemq-listener}[HiveMQ config details^].
|`password-type` |`HASHED` |How passwords are stored in the `credentials.xml` configuration file. Can either bei `PLAIN` for plain text passwords, or `HASHED` for a salted password hash.
|===

NOTE: The `listener-names` feature requires the use of at least HiveMQ 4.1 / HiveMQ CE 2020.1

==== Need help?

If you encounter any problems, we are happy to help. The best place to get in contact is our {hivemq-support}[support^].
Expand Down
29 changes: 27 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

<groupId>com.hivemq.extension</groupId>
<artifactId>hivemq-file-rbac-extension</artifactId>
<version>4.0.1</version>
<version>4.4.0</version>

<description>HiveMQ File Role Based Access Control Extension</description>

Expand All @@ -36,7 +36,7 @@
<dependency>
<groupId>com.hivemq</groupId>
<artifactId>hivemq-extension-sdk</artifactId>
<version>4.0.0</version>
<version>4.4.0</version>
</dependency>

<dependency>
Expand Down Expand Up @@ -248,6 +248,31 @@
</plugins>
</build>
</profile>
<profile>
<id>RunWithHiveMQ</id>
<build>
<plugins>
<plugin>
<groupId>com.hivemq</groupId>
<artifactId>hivemq-maven-plugin</artifactId>
<version>4.0.2</version>
<executions>
<execution>
<id>hivemq</id>
<phase>package</phase>
<goals>
<goal>hivemq</goal>
</goals>
<configuration>
<hiveMQDir>YOUR_HIVEMQ_FOLDER</hiveMQDir>
<debugMode>SERVER</debugMode>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

package com.hivemq.extensions.rbac;

import com.hivemq.extension.sdk.api.client.parameter.Listener;
import com.hivemq.extensions.rbac.configuration.entities.ExtensionConfig;
import com.hivemq.extensions.rbac.utils.CredentialsValidator;
import com.hivemq.extension.sdk.api.annotations.NotNull;
import com.hivemq.extension.sdk.api.auth.SimpleAuthenticator;
Expand All @@ -29,18 +31,31 @@
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Optional;
import java.util.Set;

public class FileAuthAuthenticator implements SimpleAuthenticator {

private final @NotNull
CredentialsValidator credentialsValidator;
private final @NotNull CredentialsValidator credentialsValidator;

FileAuthAuthenticator(final @NotNull CredentialsValidator credentialsValidator) {
private final @NotNull ExtensionConfig extensionConfig;

FileAuthAuthenticator(final @NotNull CredentialsValidator credentialsValidator, final @NotNull ExtensionConfig extensionConfig) {
this.credentialsValidator = credentialsValidator;
this.extensionConfig = extensionConfig;
}

@Override
public void onConnect(@NotNull final SimpleAuthInput simpleAuthInput, @NotNull final SimpleAuthOutput simpleAuthOutput) {
final Set<String> listenerNames = extensionConfig.getListenerNames();
final Optional<Listener> connectedListenerOptional = simpleAuthInput.getConnectionInformation().getListener();

if( listenerNames != null && !listenerNames.isEmpty() && connectedListenerOptional.isPresent()) {
final String connectedListenerName = connectedListenerOptional.get().getName();
if(!listenerNames.contains(connectedListenerName)) {
simpleAuthOutput.nextExtensionOrDefault();
return;
}
}

final Optional<String> userNameOptional = simpleAuthInput.getConnectPacket().getUserName();
final Optional<ByteBuffer> passwordOptional = simpleAuthInput.getConnectPacket().getPassword();
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/com/hivemq/extensions/rbac/FileAuthMain.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package com.hivemq.extensions.rbac;

import com.hivemq.extensions.rbac.configuration.entities.ExtensionConfig;
import com.hivemq.extensions.rbac.utils.CredentialsValidator;
import com.hivemq.extension.sdk.api.ExtensionMain;
import com.hivemq.extension.sdk.api.annotations.NotNull;
Expand Down Expand Up @@ -54,7 +55,9 @@ public void extensionStart(final @NotNull ExtensionStartInput extensionStartInpu
extensionConfiguration.getExtensionConfig(), Services.metricRegistry());
credentialsValidator.init();

Services.securityRegistry().setAuthenticatorProvider(new FileAuthenticatorProvider(credentialsValidator));
final ExtensionConfig extensionConfig = extensionConfiguration.getExtensionConfig();

Services.securityRegistry().setAuthenticatorProvider(new FileAuthenticatorProvider(credentialsValidator,extensionConfig));

} catch (Exception e) {
log.error("Exception thrown at extension start: ", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package com.hivemq.extensions.rbac;

import com.hivemq.extensions.rbac.configuration.entities.ExtensionConfig;
import com.hivemq.extensions.rbac.utils.CredentialsValidator;
import com.hivemq.extension.sdk.api.annotations.NotNull;
import com.hivemq.extension.sdk.api.annotations.Nullable;
Expand All @@ -28,8 +29,8 @@ public class FileAuthenticatorProvider implements AuthenticatorProvider {

private final @NotNull FileAuthAuthenticator authenticator;

FileAuthenticatorProvider(@NotNull final CredentialsValidator credentialsValidator) {
this.authenticator = new FileAuthAuthenticator(credentialsValidator);
FileAuthenticatorProvider(@NotNull final CredentialsValidator credentialsValidator, @NotNull final ExtensionConfig extensionConfig) {
this.authenticator = new FileAuthAuthenticator(credentialsValidator,extensionConfig);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@
package com.hivemq.extensions.rbac.configuration.entities;

import com.hivemq.extension.sdk.api.annotations.NotNull;
import com.hivemq.extension.sdk.api.annotations.Nullable;

import javax.xml.bind.annotation.*;
import java.util.List;
import java.util.Set;


@XmlRootElement(name = "extension-configuration")
Expand All @@ -29,16 +32,22 @@ public class ExtensionConfig {

@XmlElement(name = "credentials-reload-interval", required = false, defaultValue = "60")
private int reloadInterval = 60;

@Nullable
@XmlElementWrapper(name = "listener-names")
@XmlElement(name = "listener-name")
private Set<String> listenerNames;

@NotNull
@XmlElement(name = "password-type", required = false, defaultValue = "HASHED")
private PasswordType passwordType = PasswordType.HASHED;


public ExtensionConfig() {
}

public ExtensionConfig(final int reloadInterval, final @NotNull PasswordType passwordType) {
public ExtensionConfig(final int reloadInterval, final Set<String> listenerNames, final @NotNull PasswordType passwordType) {
this.reloadInterval = reloadInterval;
this.listenerNames = listenerNames;
this.passwordType = passwordType;
}

Expand All @@ -50,6 +59,14 @@ public void setReloadInterval(final int reloadInterval) {
this.reloadInterval = reloadInterval;
}

public Set<String> getListenerNames() {
return listenerNames;
}

public void setListenerNames(Set<String> listenerNames) {
this.listenerNames = listenerNames;
}

@NotNull
public PasswordType getPasswordType() {
return passwordType;
Expand All @@ -64,6 +81,7 @@ public void setPasswordType(final @NotNull PasswordType passwordType) {
public String toString() {
return "ExtensionConfiguration{" +
"reloadInterval=" + reloadInterval +
", listenerNames=" + listenerNames +
", passwordType=" + passwordType +
'}';
}
Expand Down
6 changes: 6 additions & 0 deletions src/main/resources/extension-config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
<!-- Reload interval for credentials in seconds -->
<credentials-reload-interval>60</credentials-reload-interval>

<!-- Optional list of names of listeners this extension is used for
<listener-names>
<listener-name>my-listener</listener-name>
<listener-name>my-listener-2</listener-name>
</listener-names> -->

<!-- If the credentials file is using HASHED or PLAIN passwords -->
<password-type>HASHED</password-type>

Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/hivemq-extension.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@
<name>${extension.name}</name>
<version>${version}</version>
<priority>1000</priority>
<author>dc-square GmbH</author>
<author>HiveMQ GmbH</author>
</hivemq-extension>
Loading