Category: Java

  • Creating a simple endpoint in Java and Spring Boot to authenticate using Active Directory

    Well, guys, how are you doing? Yes, I’ll be quite straightforward: I’ll show you a working code in Java using the framework Spring Boot and Windows Server Active Directory.

    Let me contextualize: you have Active Directory running in a Windows Server machine (not necessarily on the same machine as the current code) and, in order to harness the users’ authentication data from the company domain as the authentication method of a third-party software, you have to create an endpoint and make it available to the other software. You don’t need a VIEW in the MVC Architecture.

    Model class: AuthenticationRequest

    public class AuthenticationRequest {
        private String username;
        private String password;
    
        // Getters and setters
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    }
    

    RestController: AuthenticationController

    import model.AuthenticationRequest;
    import java.util.Hashtable;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.http.ResponseEntity;
    import org.springframework.http.HttpStatus;
    import javax.naming.*;
    import javax.naming.directory.*;
    
    @RestController
    public class AuthenticationController {
    
        @PostMapping("/authenticate")
        public ResponseEntity<String> authenticateUser(@RequestBody AuthenticationRequest request) {
            try {
                String username = request.getUsername();
                String password = request.getPassword();
    
                boolean isAuthenticated = authenticateWithActiveDirectory(username, password);
    
                if (isAuthenticated) {
                    return new ResponseEntity<>("User authenticated successfully", HttpStatus.OK);
                } else {
                    return new ResponseEntity<>("Authentication failed", HttpStatus.UNAUTHORIZED);
                }
            } catch (Exception e) {
                // Log the exception or handle it appropriately
                e.printStackTrace();
                return new ResponseEntity<>("Authentication failed. Erro", HttpStatus.UNAUTHORIZED);
                // return new ResponseEntity<>("An error occurred during authentication", HttpStatus.INTERNAL_SERVER_ERROR);
            }
        }
    
        private boolean authenticateWithActiveDirectory(String username, String password) {
            String ldapURL = "ldap://192.168.0.2:389";
    
            Hashtable<String, String> env = new Hashtable<>();
            env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
            env.put(Context.PROVIDER_URL, ldapURL);
            env.put(Context.SECURITY_AUTHENTICATION, "simple");
            env.put(Context.SECURITY_PRINCIPAL, username + "@intranet.company.com.br");
            env.put(Context.SECURITY_CREDENTIALS, password);
    
            try {
                DirContext context = new InitialDirContext(env);
                System.out.println("Conexão bem sucedida!");
                context.close();
                return true;
            } catch (AuthenticationException authEx) {
                System.out.println("Autenticação falhou: " + authEx.getMessage());
                return false;
            } catch (NamingException nex) {
                System.out.println("Falha ao tentar conectar com o servidor LDAP: " + nex.getMessage());
                return false;
            }
        }
    }
    

    Main Class

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class MainApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(MainApplication.class, args);
        }
    }
    

    application.properties file

    logging.level.org.springframework=INFO
    logging.level.com.example=DEBUG
    
    server.port=8444
    server.ssl.keystore=file:/C:/xampp/ssl/certificates/keystore.p12
    server.ssl.key-store-type=PKCS12
    server.ssl.key-store-password=pass
    server.ssl.key-alias=endpoint
    

    An important information is that we call this endpoint through an HTTPS POST request, so we need to generate the keystore.p12 file from the certificate provided by the certification authority. In case you don’t need to use SSL, you won’t need to worry about the last part of the previous file.

    Well… I have nothing else to say about it. It’s done! But… ah, yes! Before I go, let me remind you: please execute the Main Class and it will start your application server (like Tomcat), and your endpoint will be ready to receive and handle HTTPS requests.

    By Igor Magalhães Oliveira

  • String and StringBuider for Everybody!

    Hey! Are you one of the millions enthusiasts of String? Are you always doing something like str += “concatenate another string”?

    Pretty good! Uh… unfortunately I’m joking, but calm down. I do the diagnosis and provide you the medicines too.

    I explain: it turns out that a String object is immutable (each time you do “+=” you create another String object, with huge impact in processing time), while a StringBuilder is mutable and, because of that, far more efficient for that purpose.

    Use the String class when you need to store immutable data to be read later, like names, addresses, API endpoints, file paths… For all other cases (except multithreaded environments, where you might use StringBuffer), you’ll use StringBuilder.

    I give you some examples.

    Example 1: String concatenation

    StringBuilder message = new StringBuilder("Hello");
    message.append(" ");
    message.append("World!");
    System.out.println(message.toString());
    

    Example 2: Building dynamic strings

    StringBuilder jsonBuilder = new StringBuilder();
    jsonBuilder.append("{");
    jsonBuilder.append("\"name\": \"John\",");
    jsonBuilder.append("\"age\": 30");
    jsonBuilder.append("}");
    

    When you do a benchmarking test comparing String and StringBuilder, the results are awesome, as we see in the code below:

    int n = 10000;
    long startTime = System.nanoTime();
    long endTime;
    
    // Using String
    String result = "";
    for (int i = 0; i < n; i++) {
        result += "a";
    }
    endTime = System.nanoTime();
    long durationString = endTime - startTime;
    
    System.out.println("String concatenation took: " + durationString + " nanoseconds");
    
    // Using StringBuilder
    startTime = System.nanoTime();
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < n; i++) {
        sb.append("a");
    }
    String resultStringBuilder = sb.toString();
    endTime = System.nanoTime();
    long durationStringBuilder = endTime - startTime;
    
    System.out.println("StringBuilder concatenation took: " + durationStringBuilder + " nanoseconds");
    

    With the result as shown below:

    Well, for today it’s enough! See you soon!

    By Igor Magalhães Oliveira