/** * Verifies that for single tenant mode, the tenant is automatically set to {@link Constants#DEFAULT_TENANT}. */ @Test public void testTenantFromUserSingleTenant() { final UsernamePasswordCredentials mqttUsernamePassword = UsernamePasswordCredentials.create(TEST_USER, TEST_PASSWORD, true); assertEquals(CredentialsConstants.SECRETS_TYPE_HASHED_PASSWORD, mqttUsernamePassword.getType()); assertEquals(Constants.DEFAULT_TENANT, mqttUsernamePassword.getTenantId()); assertEquals(TEST_USER, mqttUsernamePassword.getAuthId()); assertEquals(TEST_PASSWORD, mqttUsernamePassword.getPassword()); } }
credentials = new UsernamePasswordCredentials(Constants.DEFAULT_TENANT, username); } else { return null; } else { credentials = new UsernamePasswordCredentials(userComponents[1], userComponents[0]);
final String[] fields = AuthenticationConstants.parseSaslResponse(saslResponse); final UsernamePasswordCredentials credentials = UsernamePasswordCredentials .create(fields[1], fields[2], config.isSingleTenant()); if (credentials == null) { items.put(MessageHelper.APP_PROPERTY_TENANT_ID, credentials.getTenantId()); items.put("auth_id", credentials.getAuthId()); currentSpan.log(items); getTenantObject(credentials.getTenantId()).map(tenant -> { if (tenant.isAdapterEnabled(Constants.PROTOCOL_ADAPTER_TYPE_AMQP)) { getUsernamePasswordAuthProvider().authenticate(credentials, currentSpan.context(), completer);
/** * Creates a {@link UsernamePasswordCredentials} instance from auth info provided by a * device. * <p> * The JSON object passed in is required to contain a <em>username</em> and a * <em>password</em> property. * * @param authInfo The credentials provided by the device. * @return The {@link UsernamePasswordCredentials} instance created from the auth info or * {@code null} if the auth info does not contain the required information. * @throws NullPointerException if the auth info is {@code null}. */ @Override protected DeviceCredentials getCredentials(final JsonObject authInfo) { try { final String username = authInfo.getString("username"); final String password = authInfo.getString("password"); if (username == null || password == null) { return null; } else { return UsernamePasswordCredentials.create(username, password, config.isSingleTenant()); } } catch (ClassCastException e) { return null; } }
@Override protected Future<Device> doValidateCredentials( final UsernamePasswordCredentials deviceCredentials, final CredentialsObject credentialsOnRecord) { final Context currentContext = Vertx.currentContext(); if (currentContext == null) { return Future.failedFuture(new IllegalStateException("not running on vert.x Context")); } else { final Future<Device> result = Future.future(); currentContext.executeBlocking(blockingCodeHandler -> { log.debug("validating password hash on vert.x worker thread [{}]", Thread.currentThread().getName()); final boolean isValid = credentialsOnRecord.getCandidateSecrets().stream() .anyMatch(candidateSecret -> pwdEncoder.matches(deviceCredentials.getPassword(), candidateSecret)); if (isValid) { blockingCodeHandler.complete(new Device(deviceCredentials.getTenantId(), credentialsOnRecord.getDeviceId())); } else { blockingCodeHandler.fail(new ClientErrorException(HttpURLConnection.HTTP_UNAUTHORIZED, "bad credentials")); } }, false, result); return result; } } }
/** * Matches the credentials against a given secret. * <p> * The secret is expected to be of type <em>hashed-password</em> as defined by * <a href="https://www.eclipse.org/hono/api/credentials-api/#hashed-password">Hono's Credentials API</a>. * * @param candidateSecret The secret to match against. * @return {@code true} if the credentials match the secret. */ @Override public boolean matchesCredentials(final JsonObject candidateSecret) { try { final EncodedPassword encodedPassword = EncodedPassword.fromHonoSecret(candidateSecret); return encodedPassword.matches(getPassword()); } catch (final IllegalArgumentException e) { if (LOG.isDebugEnabled()) { LOG.debug("cannot decode malformed Base64 encoded property", e); } return false; } catch (final ClassCastException e) { // one or more of the properties are not of expected type if (LOG.isDebugEnabled()) { LOG.debug("cannot process malformed candidate hashed-password secret returned by Credentials service [{}]", candidateSecret.encodePrettily()); } return false; } }
/** * Creates a {@link UsernamePasswordCredentials} instance from auth info provided by a * device. * <p> * The JSON object passed in is required to contain a <em>username</em> and a * <em>password</em> property. * * @param authInfo The credentials provided by the device. * @return The {@link UsernamePasswordCredentials} instance created from the auth info or * {@code null} if the auth info does not contain the required information. * @throws NullPointerException if the auth info is {@code null}. */ @Override protected UsernamePasswordCredentials getCredentials(final JsonObject authInfo) { try { final String username = authInfo.getString("username"); final String password = authInfo.getString("password"); if (username == null || password == null) { return null; } else { return UsernamePasswordCredentials.create(username, password, config.isSingleTenant()); } } catch (ClassCastException e) { return null; } }
/** * Verifies that in multi tenant mode, a username containing userId@tenantId leads to a correctly filled instance. */ @Test public void testTenantFromUserMultiTenant() { final UsernamePasswordCredentials mqttUsernamePassword = UsernamePasswordCredentials.create(TEST_USER_OTHER_TENANT, TEST_PASSWORD, false); assertEquals(CredentialsConstants.SECRETS_TYPE_HASHED_PASSWORD, mqttUsernamePassword.getType()); assertEquals(TEST_OTHER_TENANT, mqttUsernamePassword.getTenantId()); assertEquals(TEST_USER, mqttUsernamePassword.getAuthId()); assertEquals(TEST_PASSWORD, mqttUsernamePassword.getPassword()); }
/** * Verifies that if no tenantId is present in the username, the created object for multi tenant mode is null. */ @Test public void testTenantFromUserMultiTenantWrongUsername() { final UsernamePasswordCredentials mqttUserNamePassword = UsernamePasswordCredentials.create(TEST_USER, TEST_PASSWORD, false); assertNull(mqttUserNamePassword); }
credentials = new UsernamePasswordCredentials(Constants.DEFAULT_TENANT, username); } else { return null; } else { credentials = new UsernamePasswordCredentials(userComponents[1], userComponents[0]);
/** * Verifies that if username does not comply to the structure authId@tenantId, the created object for multi tenant mode is null. */ @Test public void testTenantFromUserMultiTenantWrongUsernameStructure() { final UsernamePasswordCredentials mqttUserNamePassword = UsernamePasswordCredentials.create("user/tenant", TEST_PASSWORD, false); assertNull(mqttUserNamePassword); }
/** * Verifies that the provider fails to validate wrong credentials. * * @param ctx The vert.x test context. */ @Test public void testAuthenticateFailsForWrongCredentials(final TestContext ctx) { when(pwdEncoder.matches(eq("wrong_pwd"), any(JsonObject.class))).thenReturn(false); deviceCredentials = UsernamePasswordCredentials.create("device@DEFAULT_TENANT", "wrong_pwd", false); vertx.runOnContext(go -> { provider.authenticate(deviceCredentials, null, ctx.asyncAssertFailure(e -> { final ClientErrorException error = (ClientErrorException) e; ctx.assertEquals(HttpURLConnection.HTTP_UNAUTHORIZED, error.getErrorCode()); })); }); }
.create(endpoint.auth().userName(), endpoint.auth().password(), getConfig().isSingleTenant());
.create(endpoint.auth().getUsername(), endpoint.auth().getPassword(), getConfig().isSingleTenant());