diff --git a/pom.xml b/pom.xml index 8b3df8de0d..99e9d5a7e3 100644 --- a/pom.xml +++ b/pom.xml @@ -237,6 +237,7 @@ liquibase spring-boot-property-exp mockserver + undertow diff --git a/undertow/pom.xml b/undertow/pom.xml new file mode 100644 index 0000000000..a0f2dc53ee --- /dev/null +++ b/undertow/pom.xml @@ -0,0 +1,58 @@ + + 4.0.0 + com.baeldung.undertow + undertow + jar + 1.0-SNAPSHOT + undertow + http://maven.apache.org + + + 1.8 + 1.8 + + + + + io.undertow + undertow-core + 1.4.18.Final + + + io.undertow + undertow-servlet + 1.4.18.Final + + + + + ${project.artifactId} + + + org.apache.maven.plugins + maven-shade-plugin + + + package + + shade + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + com.baeldung.undertow.SimpleServer + + + + + + + + \ No newline at end of file diff --git a/undertow/src/main/java/com/baeldung/undertow/SimpleServer.java b/undertow/src/main/java/com/baeldung/undertow/SimpleServer.java new file mode 100644 index 0000000000..7f869746be --- /dev/null +++ b/undertow/src/main/java/com/baeldung/undertow/SimpleServer.java @@ -0,0 +1,16 @@ +package com.baeldung.undertow; + +import io.undertow.Undertow; +import io.undertow.util.Headers; + +public class SimpleServer { + + public static void main(String[] args) { + Undertow server = Undertow.builder().addHttpListener(8080, "localhost").setHandler(exchange -> { + exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain"); + exchange.getResponseSender().send("Hello Baeldung"); + }).build(); + server.start(); + } + +} diff --git a/undertow/src/main/java/com/baeldung/undertow/ftp/FileServer.java b/undertow/src/main/java/com/baeldung/undertow/ftp/FileServer.java new file mode 100644 index 0000000000..90cad9ebbd --- /dev/null +++ b/undertow/src/main/java/com/baeldung/undertow/ftp/FileServer.java @@ -0,0 +1,20 @@ +package com.baeldung.undertow.ftp; + +import java.nio.file.Paths; + +import io.undertow.Undertow; +import io.undertow.server.handlers.resource.PathResourceManager; + +import static io.undertow.Handlers.resource; + +public class FileServer { + + public static void main(String[] args) { + Undertow server = Undertow.builder().addHttpListener(8080, "localhost") + .setHandler(resource(new PathResourceManager(Paths.get(System.getProperty("user.home")), 100)) + .setDirectoryListingEnabled(true)) + .build(); + server.start(); + } + +} diff --git a/undertow/src/main/java/com/baeldung/undertow/secure/CustomIdentityManager.java b/undertow/src/main/java/com/baeldung/undertow/secure/CustomIdentityManager.java new file mode 100644 index 0000000000..e0984f65a5 --- /dev/null +++ b/undertow/src/main/java/com/baeldung/undertow/secure/CustomIdentityManager.java @@ -0,0 +1,77 @@ +package com.baeldung.undertow.secure; + +import java.security.Principal; +import java.util.Arrays; +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +import io.undertow.security.idm.Account; +import io.undertow.security.idm.Credential; +import io.undertow.security.idm.PasswordCredential; + +public class CustomIdentityManager implements io.undertow.security.idm.IdentityManager { + + private final Map users; + + CustomIdentityManager(final Map users) { + this.users = users; + } + + @Override + public Account verify(Account account) { + return account; + } + + @Override + public Account verify(Credential credential) { + return null; + } + + @Override + public Account verify(String id, Credential credential) { + Account account = getAccount(id); + if (account != null && verifyCredential(account, credential)) { + return account; + } + return null; + } + + private boolean verifyCredential(Account account, Credential credential) { + if (credential instanceof PasswordCredential) { + char[] password = ((PasswordCredential) credential).getPassword(); + char[] expectedPassword = users.get(account.getPrincipal().getName()); + + return Arrays.equals(password, expectedPassword); + } + return false; + } + + private Account getAccount(final String id) { + if (users.containsKey(id)) { + return new Account() { + + private static final long serialVersionUID = 1L; + + private final Principal principal = new Principal() { + @Override + public String getName() { + return id; + } + }; + + @Override + public Principal getPrincipal() { + return principal; + } + + @Override + public Set getRoles() { + return Collections.emptySet(); + } + }; + } + return null; + } + +} diff --git a/undertow/src/main/java/com/baeldung/undertow/secure/SecureServer.java b/undertow/src/main/java/com/baeldung/undertow/secure/SecureServer.java new file mode 100644 index 0000000000..6f520944db --- /dev/null +++ b/undertow/src/main/java/com/baeldung/undertow/secure/SecureServer.java @@ -0,0 +1,52 @@ +package com.baeldung.undertow.secure; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import io.undertow.Undertow; +import io.undertow.io.IoCallback; +import io.undertow.security.api.AuthenticationMechanism; +import io.undertow.security.api.AuthenticationMode; +import io.undertow.security.api.SecurityContext; +import io.undertow.security.handlers.AuthenticationCallHandler; +import io.undertow.security.handlers.AuthenticationConstraintHandler; +import io.undertow.security.handlers.AuthenticationMechanismsHandler; +import io.undertow.security.handlers.SecurityInitialHandler; +import io.undertow.security.idm.IdentityManager; +import io.undertow.security.impl.BasicAuthenticationMechanism; +import io.undertow.server.HttpHandler; +import io.undertow.server.HttpServerExchange; + +public class SecureServer { + + public static void main(String[] args) { + final Map users = new HashMap<>(2); + users.put("root", "password".toCharArray()); + users.put("admin", "password".toCharArray()); + + final IdentityManager idm = new CustomIdentityManager(users); + + Undertow server = Undertow.builder().addHttpListener(8080, "localhost").setHandler(addSecurity((exchange) -> { + final SecurityContext context = exchange.getSecurityContext(); + exchange.getResponseSender().send("Hello " + context.getAuthenticatedAccount().getPrincipal().getName(), + IoCallback.END_EXCHANGE); + }, idm)).build(); + + server.start(); + + } + + private static HttpHandler addSecurity(final HttpHandler toWrap, final IdentityManager identityManager) { + HttpHandler handler = toWrap; + handler = new AuthenticationCallHandler(handler); + handler = new AuthenticationConstraintHandler(handler); + final List mechanisms = Collections + . singletonList(new BasicAuthenticationMechanism("Baeldung_Realm")); + handler = new AuthenticationMechanismsHandler(handler, mechanisms); + handler = new SecurityInitialHandler(AuthenticationMode.PRO_ACTIVE, identityManager, handler); + return handler; + } + +} diff --git a/undertow/src/main/java/com/baeldung/undertow/socket/SocketServer.java b/undertow/src/main/java/com/baeldung/undertow/socket/SocketServer.java new file mode 100644 index 0000000000..9e0e065c3a --- /dev/null +++ b/undertow/src/main/java/com/baeldung/undertow/socket/SocketServer.java @@ -0,0 +1,36 @@ +package com.baeldung.undertow.socket; + +import io.undertow.Undertow; +import io.undertow.server.handlers.resource.ClassPathResourceManager; +import io.undertow.websockets.core.AbstractReceiveListener; +import io.undertow.websockets.core.BufferedTextMessage; +import io.undertow.websockets.core.WebSocketChannel; +import io.undertow.websockets.core.WebSockets; + +import static io.undertow.Handlers.path; +import static io.undertow.Handlers.resource; +import static io.undertow.Handlers.websocket; + +public class SocketServer { + + public static void main(String[] args) { + Undertow server = Undertow.builder().addHttpListener(8080, "localhost") + .setHandler(path().addPrefixPath("/baeldungApp", websocket((exchange, channel) -> { + channel.getReceiveSetter().set(new AbstractReceiveListener() { + @Override + protected void onFullTextMessage(WebSocketChannel channel, BufferedTextMessage message) { + final String messageData = message.getData(); + for (WebSocketChannel session : channel.getPeerConnections()) { + WebSockets.sendText(messageData, session, null); + } + } + }); + channel.resumeReceives(); + })).addPrefixPath("/", resource(new ClassPathResourceManager(SocketServer.class.getClassLoader(), + SocketServer.class.getPackage())).addWelcomeFiles("index.html"))) + .build(); + + server.start(); + } + +}