Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
e1aa4f2
Synchronizing device list with Eclipse Hono.
BrandonSchmitt Aug 5, 2019
659fce1
Use devices' credentials stored in Hono to authenticate.
BrandonSchmitt Aug 8, 2019
884b54d
Add Spring Cloud Stream to move to event driven synchronization.
BrandonSchmitt Aug 19, 2019
b77c093
Sync with Hono on startup
BrandonSchmitt Aug 21, 2019
cf2a408
Allow frontend users to initiate the sync process for their current t…
BrandonSchmitt Aug 26, 2019
e441ff3
Refactor class and package structure regarding hono credentials logic
BrandonSchmitt Sep 2, 2019
8ead86d
Sync device if not present when it could successfully authenticate.
BrandonSchmitt Sep 5, 2019
d89df5a
Refactor Hono Configuration
BrandonSchmitt Sep 5, 2019
5c55c2a
Make Hono optional
BrandonSchmitt Sep 5, 2019
f188598
Hono sync documentation
BrandonSchmitt Sep 5, 2019
0fee1bf
Add missing Kiwigrid GmbH licences
BrandonSchmitt Sep 5, 2019
458d5b5
Disable CUD permissions and ui buttons concerning targets when Hono s…
BrandonSchmitt Sep 5, 2019
01f0995
Use better placeholder for OIDC realm in hawkbit.dmf.hono.oidc-token-uri
BrandonSchmitt Sep 5, 2019
1ae10d3
Add new line at end of license file
BrandonSchmitt Sep 12, 2019
a2d8f04
Fix NullPointerException if there are no tenants in Hono yet.
BrandonSchmitt Sep 16, 2019
95f60ac
Split off target filter permissions from target permissions.
BrandonSchmitt Oct 10, 2019
453e5da
hono sync: Allow using a different target name than the device id.
BrandonSchmitt Oct 11, 2019
3275042
Add encoding to the URLEncoder.
BrandonSchmitt Oct 11, 2019
e9675dc
Fix credential polling.
BrandonSchmitt Oct 16, 2019
24d1fed
Update Tests.
BrandonSchmitt Oct 21, 2019
95bbe04
Require targetNameFieldInDeviceExtension to be not empty for it to be…
BrandonSchmitt Nov 4, 2019
b06a5d9
Undo UPDATE_TARGET revokation as it is needed to assign targets to di…
BrandonSchmitt Nov 7, 2019
5101354
Log error during credential fetching.
BrandonSchmitt Nov 14, 2019
724ba90
Allow hawkBit to use an OIDC service account.
BrandonSchmitt Nov 14, 2019
dc711e9
Add "none" as hash function.
BrandonSchmitt Nov 22, 2019
9256fdf
Sync target tags if they are in the `ext` field.
BrandonSchmitt Nov 22, 2019
82425ca
Remove description as it is easily to long.
BrandonSchmitt Nov 27, 2019
7d31d5e
Merge branch 'master' into hono-sync
BrandonSchmitt Jan 16, 2020
a7420f3
Allow Hono API URLs to predefine arguments.
BrandonSchmitt Jul 13, 2020
b269b5a
Merge branch 'master' into hono-sync
BrandonSchmitt Jul 13, 2020
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
48 changes: 48 additions & 0 deletions docs/content/guides/runhawkbit.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,54 @@ spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
```

### Set [Eclipse Hono](https://www.eclipse.org/hono/) as hawkBit's device registry

```
hawkbit.dmf.hono.enabled=true
hawkbit.dmf.hono.tenant-list-uri=http://HONO_HOST/v1/tenants
hawkbit.dmf.hono.device-list-uri=http://HONO_HOST/v1/devices/$tenantId
hawkbit.dmf.hono.credentials-list-uri=http://HONO_HOST/v1/credentials/$tenantId/$deviceId
```
`$tenantId` and `$deviceId` are placeholders which will be replaced by hawkBit during the respective requests.

hawkBit currently supports three different methods to authenticate with hono:
- None (`none`; default)
- BasicAuth (`basic`)
- OpenID Connect (`oidc`)

If you intend to use any authentication method other than `none` you must provide these additional properties:

```
hawkbit.dmf.hono.authentication-method=oidc
hawkbit.dmf.hono.username=USERNAME
hawkbit.dmf.hono.password=PASSWORD

// Only for authentication-method = oidc
hawkbit.dmf.hono.oidc-token-uri=http://OIDC_HOST/auth/realms/REALM/protocol/openid-connect/token
hawkbit.dmf.hono.oidc-client-id=OIDC_CLIENT_ID
hawkbit.dmf.hono.oidc-client-secret=OIDC_CLIENT_SECRET # You can use a oidc client secret instead of username+password
```

hawkBit handles device registry updates through CUD events emitted by Hono over any Spring Cloud Stream supported channel, such as AMQP or Google Cloud Pub/Sub.

In order to have predictable channel names use the following properties:
```
spring.cloud.stream.bindings.device-created.destination=device-registry.device-created
spring.cloud.stream.bindings.device-created.group=hawkBit
spring.cloud.stream.bindings.device-updated.destination=device-registry.device-updated
spring.cloud.stream.bindings.device-updated.group=hawkBit
spring.cloud.stream.bindings.device-deleted.destination=device-registry.device-deleted
spring.cloud.stream.bindings.device-deleted.group=hawkBit
```
For Google Cloud Pub/Sub disable the default Maven profile `hono-amqp` and enable the profile `amqp-gcp-pubsub`.

Additionally, you can specify a field of the device's extension object which will be used as the corresponding target's name:
```
hawkbit.dmf.hono.target-name-field=fancyFieldName
```
If none is specified the device's ID is used as the target's name.


### Adapt hostname of example scenario [creation script](https://github.com/eclipse/hawkbit-examples/blob/master/hawkbit-example-mgmt-simulator/src/main/resources/application.properties)

Should only be necessary if your system does not run on localhost or uses a different port than the example app.
Expand Down
8 changes: 7 additions & 1 deletion hawkbit-autoconfigure/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,18 @@
<version>${project.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-dmf-amqp</artifactId>
<version>${project.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-dmf-hono</artifactId>
<version>${project.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-ui</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Copyright (c) 2019 Kiwigrid GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.autoconfigure.dmf.hono;

import org.eclipse.hawkbit.dmf.hono.DmfHonoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

/**
* The Eclipse Hono based device Management Federation API (DMF) auto configuration.
*/
@Configuration
@ConditionalOnClass(DmfHonoConfiguration.class)
@Import(DmfHonoConfiguration.class)
public class DmfHonoAutoConfiguration {
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.eclipse.hawkbit.cache.DownloadIdCache;
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
import org.eclipse.hawkbit.ddi.rest.resource.DdiApiConfiguration;
import org.eclipse.hawkbit.dmf.hono.HonoDeviceSync;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.im.authentication.TenantUserPasswordAuthenticationToken;
Expand All @@ -40,15 +41,18 @@
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticateAnonymousDownloadFilter;
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticateSecurityTokenFilter;
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticatedGatewaySecurityTokenFilter;
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticatedHonoFilter;
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticatedSecurityHeaderFilter;
import org.eclipse.hawkbit.security.HttpDownloadAuthenticationFilter;
import org.eclipse.hawkbit.security.PreAuthHonoAuthenticationProvider;
import org.eclipse.hawkbit.security.PreAuthTokenSourceTrustAuthenticationProvider;
import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.eclipse.hawkbit.ui.MgmtUiConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
Expand Down Expand Up @@ -165,6 +169,9 @@ static class ControllerSecurityConfigurationAdapter extends WebSecurityConfigure
private final HawkbitSecurityProperties securityProperties;
private final SystemSecurityContext systemSecurityContext;

@Autowired(required = false)
private HonoDeviceSync honoDeviceSync;

@Autowired
ControllerSecurityConfigurationAdapter(final ControllerManagement controllerManagement,
final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware,
Expand Down Expand Up @@ -213,6 +220,17 @@ protected void configure(final HttpSecurity http) throws Exception {
securityHeaderFilter.setCheckForPrincipalChanges(true);
securityHeaderFilter.setAuthenticationDetailsSource(authenticationDetailsSource);


HttpControllerPreAuthenticatedHonoFilter honoFilter = null;
if (honoDeviceSync != null) {
honoFilter = new HttpControllerPreAuthenticatedHonoFilter(
tenantConfigurationManagement, tenantAware, controllerManagement, systemSecurityContext,
honoDeviceSync);
honoFilter.setAuthenticationManager(authenticationManager());
honoFilter.setCheckForPrincipalChanges(true);
honoFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
}

final HttpControllerPreAuthenticateSecurityTokenFilter securityTokenFilter = new HttpControllerPreAuthenticateSecurityTokenFilter(
tenantConfigurationManagement, tenantAware, controllerManagement, systemSecurityContext);
securityTokenFilter.setAuthenticationManager(authenticationManager());
Expand Down Expand Up @@ -244,7 +262,11 @@ protected void configure(final HttpSecurity http) throws Exception {
.authenticationFilter(anonymousFilter);
} else {

httpSec.addFilter(securityHeaderFilter).addFilter(securityTokenFilter)
httpSec.addFilter(securityHeaderFilter);
if (honoFilter != null) {
httpSec.addFilter(honoFilter);
}
httpSec.addFilter(securityTokenFilter)
.addFilter(gatewaySecurityTokenFilter).requestMatchers().antMatchers(DDI_ANT_MATCHERS).and()
.anonymous().disable().authorizeRequests().anyRequest().authenticated().and()
.exceptionHandling()
Expand All @@ -257,6 +279,10 @@ protected void configure(final HttpSecurity http) throws Exception {
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {

if (honoDeviceSync != null) {
auth.authenticationProvider(new PreAuthHonoAuthenticationProvider(honoDeviceSync,
ddiSecurityConfiguration.getRp().getTrustedIPs()));
}
auth.authenticationProvider(new PreAuthTokenSourceTrustAuthenticationProvider(
ddiSecurityConfiguration.getRp().getTrustedIPs()));
}
Expand All @@ -281,6 +307,9 @@ static class ControllerDownloadSecurityConfigurationAdapter extends WebSecurityC
private final HawkbitSecurityProperties securityProperties;
private final SystemSecurityContext systemSecurityContext;

@Autowired(required = false)
private HonoDeviceSync honoDeviceSync;

@Autowired
ControllerDownloadSecurityConfigurationAdapter(final ControllerManagement controllerManagement,
final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware,
Expand Down Expand Up @@ -329,6 +358,16 @@ protected void configure(final HttpSecurity http) throws Exception {
securityHeaderFilter.setCheckForPrincipalChanges(true);
securityHeaderFilter.setAuthenticationDetailsSource(authenticationDetailsSource);

HttpControllerPreAuthenticatedHonoFilter honoFilter = null;
if (honoDeviceSync != null) {
honoFilter = new HttpControllerPreAuthenticatedHonoFilter(
tenantConfigurationManagement, tenantAware, controllerManagement, systemSecurityContext,
honoDeviceSync);
honoFilter.setAuthenticationManager(authenticationManager());
honoFilter.setCheckForPrincipalChanges(true);
honoFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
}

final HttpControllerPreAuthenticateSecurityTokenFilter securityTokenFilter = new HttpControllerPreAuthenticateSecurityTokenFilter(
tenantConfigurationManagement, tenantAware, controllerManagement, systemSecurityContext);
securityTokenFilter.setAuthenticationManager(authenticationManager());
Expand Down Expand Up @@ -366,7 +405,11 @@ protected void configure(final HttpSecurity http) throws Exception {
.authenticationFilter(anonymousFilter);
} else {

httpSec.addFilter(securityHeaderFilter).addFilter(securityTokenFilter)
httpSec.addFilter(securityHeaderFilter);
if (honoFilter != null) {
httpSec.addFilter(honoFilter);
}
httpSec.addFilter(securityTokenFilter)
.addFilter(gatewaySecurityTokenFilter).addFilter(controllerAnonymousDownloadFilter)
.requestMatchers().antMatchers(DDI_DL_ANT_MATCHER).and().anonymous().disable()
.authorizeRequests().anyRequest().authenticated().and().exceptionHandling()
Expand All @@ -379,6 +422,10 @@ protected void configure(final HttpSecurity http) throws Exception {
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {

if (honoDeviceSync != null) {
auth.authenticationProvider(new PreAuthHonoAuthenticationProvider(honoDeviceSync,
ddiSecurityConfiguration.getRp().getTrustedIPs()));
}
auth.authenticationProvider(new PreAuthTokenSourceTrustAuthenticationProvider(
ddiSecurityConfiguration.getRp().getTrustedIPs()));
}
Expand Down Expand Up @@ -435,6 +482,9 @@ public static class IdRestSecurityConfigurationAdapter extends WebSecurityConfig
@Autowired
private DownloadIdCache downloadIdCache;

@Autowired(required = false)
private HonoDeviceSync honoDeviceSync;

@Override
protected void configure(final HttpSecurity http) throws Exception {

Expand All @@ -453,6 +503,10 @@ protected void configure(final HttpSecurity http) throws Exception {

@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
if (honoDeviceSync != null) {
auth.authenticationProvider(new PreAuthHonoAuthenticationProvider(honoDeviceSync,
ddiSecurityConfiguration.getRp().getTrustedIPs()));
}
auth.authenticationProvider(new PreAuthTokenSourceTrustAuthenticationProvider(
ddiSecurityConfiguration.getRp().getTrustedIPs()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ org.eclipse.hawkbit.autoconfigure.cache.CacheAutoConfiguration,\
org.eclipse.hawkbit.autoconfigure.cache.DownloadIdCacheAutoConfiguration,\
org.eclipse.hawkbit.autoconfigure.ddi.DDiApiAutoConfiguration,\
org.eclipse.hawkbit.autoconfigure.dmf.amqp.DmfApiAutoConfiguration,\
org.eclipse.hawkbit.autoconfigure.dmf.hono.DmfHonoAutoConfiguration,\
org.eclipse.hawkbit.autoconfigure.mgmt.ui.MgmtUiAutoConfiguration,\
org.eclipse.hawkbit.autoconfigure.mgmt.MgmtApiAutoConfiguration,\
org.eclipse.hawkbit.autoconfigure.repository.event.EventPublisherAutoConfiguration,\
Expand Down
48 changes: 48 additions & 0 deletions hawkbit-dmf/hawkbit-dmf-hono/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<!--

Copyright (c) 2019 Kiwigrid GmbH and others.

All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-v10.html

-->
<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>

<parent>
<artifactId>hawkbit-dmf-parent</artifactId>
<groupId>org.eclipse.hawkbit</groupId>
<version>0.3.0-SNAPSHOT</version>
</parent>
<artifactId>hawkbit-dmf-hono</artifactId>
<name>hawkBit :: DMF :: Hono</name>

<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-repository-api</artifactId>
<version>0.3.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-repository-core</artifactId>
<version>0.3.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-repository-jpa</artifactId>
<version>0.3.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
Loading