use of org.eclipse.hono.auth.HonoUser in project hono by eclipse.
the class AmqpServiceBase method setRemoteConnectionOpenHandler.
private void setRemoteConnectionOpenHandler(final ProtonConnection connection) {
connection.sessionOpenHandler(remoteOpenSession -> handleSessionOpen(connection, remoteOpenSession));
connection.receiverOpenHandler(remoteOpenReceiver -> handleReceiverOpen(connection, remoteOpenReceiver));
connection.senderOpenHandler(remoteOpenSender -> handleSenderOpen(connection, remoteOpenSender));
connection.disconnectHandler(this::handleRemoteDisconnect);
connection.closeHandler(remoteClose -> handleRemoteConnectionClose(connection, remoteClose));
connection.openHandler(remoteOpen -> {
final HonoUser clientPrincipal = Constants.getClientPrincipal(connection);
LOG.debug("client [container: {}, user: {}] connected", connection.getRemoteContainer(), clientPrincipal.getName());
// attach an ID so that we can later inform downstream components when connection is closed
connection.attachments().set(Constants.KEY_CONNECTION_ID, String.class, UUID.randomUUID().toString());
final Duration delay = Duration.between(Instant.now(), clientPrincipal.getExpirationTime());
final WeakReference<ProtonConnection> conRef = new WeakReference<>(connection);
vertx.setTimer(delay.toMillis(), timerId -> {
if (conRef.get() != null) {
closeExpiredConnection(conRef.get());
}
});
connection.open();
});
}
use of org.eclipse.hono.auth.HonoUser in project hono by eclipse.
the class AuthenticationEndpoint method onLinkAttach.
@Override
public final void onLinkAttach(final ProtonConnection con, final ProtonSender sender, final ResourceIdentifier targetResource) {
if (ProtonQoS.AT_LEAST_ONCE.equals(sender.getRemoteQoS())) {
HonoUser user = Constants.getClientPrincipal(con);
sender.setQoS(ProtonQoS.AT_LEAST_ONCE).open();
logger.debug("transferring token to client...");
Message tokenMsg = ProtonHelper.message(user.getToken());
MessageHelper.addProperty(tokenMsg, AuthenticationConstants.APPLICATION_PROPERTY_TYPE, AuthenticationConstants.TYPE_AMQP_JWT);
sender.send(tokenMsg, disposition -> {
if (disposition.remotelySettled()) {
logger.debug("successfully transferred auth token to client");
} else {
logger.debug("failed to transfer auth token to client");
}
sender.close();
});
} else {
onLinkDetach(sender, ProtonHelper.condition(AmqpError.INVALID_FIELD, "supports AT_LEAST_ONCE delivery mode only"));
}
}
use of org.eclipse.hono.auth.HonoUser in project hono by eclipse.
the class FileBasedAuthenticationService method verify.
private void verify(final String authenticationId, final JsonObject user, final String authorizationId, final Handler<AsyncResult<HonoUser>> authenticationResultHandler) {
JsonObject effectiveUser = user;
String effectiveAuthorizationId = authenticationId;
if (authorizationId != null && !authorizationId.isEmpty() && isAuthorizedToImpersonate(user)) {
JsonObject impersonatedUser = users.get(authorizationId);
if (impersonatedUser != null) {
effectiveUser = impersonatedUser;
effectiveAuthorizationId = authorizationId;
log.debug("granting authorization id specified by client");
} else {
log.debug("no user found for authorization id provided by client, granting authentication id instead");
}
}
final Authorities grantedAuthorities = getAuthorities(effectiveUser);
final String grantedAuthorizationId = effectiveAuthorizationId;
final Instant tokenExpirationTime = Instant.now().plus(tokenFactory.getTokenLifetime());
final String token = tokenFactory.createToken(grantedAuthorizationId, grantedAuthorities);
HonoUser honoUser = new HonoUser() {
@Override
public String getName() {
return grantedAuthorizationId;
}
@Override
public String getToken() {
return token;
}
@Override
public Authorities getAuthorities() {
return grantedAuthorities;
}
@Override
public boolean isExpired() {
return !Instant.now().isBefore(tokenExpirationTime);
}
@Override
public Instant getExpirationTime() {
return tokenExpirationTime;
}
};
authenticationResultHandler.handle(Future.succeededFuture(honoUser));
}
use of org.eclipse.hono.auth.HonoUser in project hono by eclipse.
the class SimpleAuthenticationServer method handleSenderOpen.
/**
* Handles a request from a client to establish a link for receiving messages from this server.
*
* @param con the connection to the client.
* @param sender the sender created for the link.
*/
@Override
protected void handleSenderOpen(final ProtonConnection con, final ProtonSender sender) {
final Source remoteSource = sender.getRemoteSource();
LOG.debug("client [{}] wants to open a link for receiving messages [address: {}]", con.getRemoteContainer(), remoteSource);
try {
final ResourceIdentifier targetResource = getResourceIdentifier(remoteSource.getAddress());
final AmqpEndpoint endpoint = getEndpoint(targetResource);
if (endpoint == null) {
LOG.debug("no endpoint registered for node [{}]", targetResource);
con.setCondition(ProtonHelper.condition(AmqpError.NOT_FOUND, "no such node")).close();
} else {
HonoUser user = Constants.getClientPrincipal(con);
if (Constants.SUBJECT_ANONYMOUS.equals(user.getName())) {
con.setCondition(ProtonHelper.condition(AmqpError.UNAUTHORIZED_ACCESS, "client must authenticate using SASL")).close();
} else {
Constants.copyProperties(con, sender);
sender.setSource(sender.getRemoteSource());
endpoint.onLinkAttach(con, sender, targetResource);
vertx.setTimer(5000, closeCon -> {
if (!con.isDisconnected()) {
LOG.debug("connection with client [{}] timed out after 5 seconds, closing connection", con.getRemoteContainer());
con.setCondition(ProtonHelper.condition("hono: inactivity", "client must retrieve token within 5 secs after opening connection")).close();
}
});
}
}
} catch (final IllegalArgumentException e) {
LOG.debug("client has provided invalid resource identifier as source address", e);
con.setCondition(ProtonHelper.condition(AmqpError.INVALID_FIELD, "malformed source address")).close();
}
}
use of org.eclipse.hono.auth.HonoUser in project hono by eclipse.
the class AmqpServiceBase method closeExpiredConnection.
/**
* Closes an expired client connection.
* <p>
* A connection is considered expired if the {@link HonoUser#isExpired()} method
* of the user principal attached to the connection returns {@code true}.
*
* @param con The client connection.
*/
protected final void closeExpiredConnection(final ProtonConnection con) {
if (!con.isDisconnected()) {
final HonoUser clientPrincipal = Constants.getClientPrincipal(con);
if (clientPrincipal != null) {
LOG.debug("client's [{}] access token has expired, closing connection", clientPrincipal.getName());
con.disconnectHandler(null);
con.closeHandler(null);
con.setCondition(ProtonHelper.condition(AmqpError.UNAUTHORIZED_ACCESS, "access token expired"));
con.close();
con.disconnect();
publishConnectionClosedEvent(con);
}
}
}
Aggregations