Tag Archives: java

How to use SPNEGO negotiation with Curl

1. First we need to check that we have an SPNEGO compatible Curl installed:

$ curl -V
curl 7.81.0 (x86_64-w64-mingw32) libcurl/7.81.0 OpenSSL/1.1.1m (Schannel) zlib/1.2.11 brotli/1.0.9 zstd/1.5.2 libidn2/2.3.1 libssh2/1.10.0 nghttp2/1.46.0
Release-Date: 2022-01-05
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS brotli HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz MultiSSL NTLM SPNEGO SSL SSPI TLS-SRP zstd

Here we can see that the SPNEGO feature is available

2. Next we need to create a credentials cache for Curl to use

kinit <username>
Password for <username>@<domain.com>: <password>

Here we create a “authentication token” and put it in a credentials cache fรถr Curl, and any other program ie. SoapUI and others, to use. ‘username’ is the name of the user. This can be omitted, and if so the default user and domain (user that runs the command) will be used instead. The ‘kinit’ command will ask for the password associated with the user. After this has been inputed the token is created

3. After that we run Curl with the following options:

curl --negotiate -u : https://a-spnego-protected-site/data-i-want-to-access

–negotiate will trigger SPNEGO behaviour
-u is needed but is left blank. On some sites though I have had to put <domain\user> to get it to work
: should point to the SPNEGO protected resource we want to access
Curl will now use the token in the credentials cache to authenticate against the web resource

Troubleshooting commands:

klist - lists all current tokens with the expiry timestamps in the cache
kdestroy - remove a ticket from the credentials cache

Tested with Curl v7.81.0 in GitBash on a Windows 10 with Java 1.8.0_301

Testing a simple web app in Mule with JUnit

A simple JUnit test for when you just can’t remember the Mule JUnit testing syntax ๐Ÿ˜‰

Mule flow
A Mule flow that takes a username as input and concatenates it with a “Hello”. The request is done by a GET call:

Flow code



    <http:listener-config 
       name="HTTP_Listener_Configuration" 
       host="0.0.0.0" 
       port="8081" 
       doc:name="HTTP Listener Configuration">
    
        <http:listener 
           config-ref="HTTP_Listener_Configuration" 
           path="/test" 
           doc:name="HTTP">
        <set-payload 
           value="#['Hello '+message.inboundProperties.'http.query.params'.username]" 
           doc:name="Set Payload">
    

Java test code:

import org.junit.Test;
import org.mule.DefaultMuleMessage;
import org.mule.api.MuleMessage;
import org.mule.api.client.MuleClient;
import org.mule.tck.junit4.FunctionalTestCase;

import junit.framework.Assert;

public class MyTests extends FunctionalTestCase {
	
	@Test
	public void testMyFlow() throws Exception {
        // Get the Mule Context
		MuleClient muleClient = muleContext.getClient();
		
        // Create an empty test Mule message
		DefaultMuleMessage message = 
                        new DefaultMuleMessage(null, muleContext);
		
        // Make a call to the tested web service
		MuleMessage responseMessage = muleClient.send(
                       "http://localhost:8081/test?username=Niklas", 
                       message
                    );
		
        // Get response as a string
		String responsePayload = responseMessage.getPayloadAsString();
		
        // Assert response
		Assert.assertEquals("Hello Niklas", responsePayload);
		
	}
	
	@Override
	protected String[] getConfigFiles() {
         // Path to the Mule configuration file that is being tested
		return new String[]{"src/main/app/helloworld.xml"};
	}

}

Tested on OSX 10.15.7, Mule 3.9.4, and JUnit 4.13

H2 Database: Missing UNIX_TIMESTAMP

So maybe you are running tests using an H2 database with your MySQL-based application, and you just got the message that the MySQL function UNIX_TIMESTAMP(value) is missing from the H2 database? No worries. With an H2 database, you can build your own UNIX_TIMESTAMP (or any other function you might need). I’m here going to show you one way to do it:

First, we need to create a class on the classpath of the application that connects to the H2 database, this is normally the application you are testing:

package h2;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class H2UserDefined {

    public static Long UNIX_TIMESTAMP(String d) throws ParseException {
        DateFormat dateFormat 
                          = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Date dateresult = dateFormat.parse(d);
        return dateresult.getTime()/1000;
    }
}

Now we need to tell H2 that we have a new function to use. To do this we need some SQL to run against the H2 database:

CREATE ALIAS UNIX_TIMESTAMP FOR "h2.H2UserDefined.UNIX_TIMESTAMP";

Here we tell the H2 database that there is a new alias called UNIX_TIMESTAMP that can be used and that it is located in the package ‘h2’ with the path ‘H2UserDefines’ and a function name UNIX_TIMESTAMP. Quite simple ๐Ÿ™‚

Tested on Play Framework 2.3.6, H2 v1.4