Thursday, September 20, 2012

So what credentials do you need?

One of the features that I am very proud of in the HTTP Analyzer in JDeveloper is the ability to test a SOAP service with the minimum of fuss. Rather than having to configure security headers and understand WS-Policy we make use of the WLS JAX-WS client to read and interpret the policies defined in the WSDL and then apply abstracted credentials.

It turns out that this feature is very popular; but there is some confusion about just what information you might need to provide for a particular policy. So here is a simple summary of what is required for what type of policy.

Username Token


The simplest page just ask for a username and password. You are going to need this for policies that contains the phrase usernametoken, username, UNT or even HttpBasic and HttpDigest. The policy dictates where the values end up whether they be in an HTTP header or a WS-Security SOAP header.




X509 Certificates


The X509 panel is the most powerful and the most misunderstood. On this panel you can define a set of certificates and keys for both the client and the server.



The simplest version of this panel would be one that just contains the server key store. This is sufficient in most policy to be able to send a server an encrypted message and receive a message back. (In the most common case the server certificate is used to encrypt a symmetrical key, most likely AES,  that can be used to decrypt the message being received.)

You will also need this to verify messages that are signed by the server.

If you need to server to trust that you send the message with signing then you have to provide a identity in the form of a Public/Private key that can be used to encrypt the outgoing hashes used to sign the message. 

This client identity can also be used in leu of the username token described earlier. In the most common policy I have worked with the CN of the public certificate is used as the user identity. 

Http Keystores


Some policies will make use of a Https channel to send messages, and like the x509 certificate panel the settings come in both client and server side store.

In the simplest case this panel will just be configured with a "Trusted Certificates Keystore", so this will list with certificates or certificate signing authorities are going to be trusted by the analyser. In order to make this as easy as possible by default we append the "CA" certificates that come with Java so you can by default connect to most publish websites without any further configuration.



This will normally be enough unless the policy is defined as 2-Way HTTPS, most of the OWSM https policies I have worked with are 2-Way by default. The WLS ones tend to specify this explicitly. In the 2-Way case you again need to prove the identity of the client, and the only way of doing this is going to be with a Public/Private key that the server trusts.

STS Configuration

The final panel regards working with policies that require SAML tokens; JDeveloper is unable to issue SAML tokens itself so instead it need to get hold of a token from a STS store that is trusted by the server you are in contact with.

In this case you need to specify the URL of the endpoint of the STS service along with a security policy that will match that on the sever side. This is unfortunately a static list and has to be figured out manually. Perhaps this is something that can be improved on in a later release.


On important feature to note is that when connecting to the STS store the analyser will be using values from the other three panels that we have discussed. This might be important if you are having trouble setting up a connection.

Wednesday, September 5, 2012

Changing delay, and hence the order, in a DelayQueue

So I was looking at building a simple object cache that expires the objects after a given time. The obvious mechanism for this is the use the DelayedQueue class from the concurrency package in Java; but I wanted to know if it way possible to update the delay after an object has been added to the queue. Looking at the Delayed interface there didn't seem to be a good reason not to in the docs so I thought it was time to experiment.

So first of all you need to to create an instance of Delayed, this is a very simple implementation that with the switch of a flag you can basically invert the timeout order in the list. (And add a suitable offset so things happen in the right order)

static int COUNT=100;


   class DelayedSwap implements Delayed, Comparable<Delayed> {

       int index = 0;
       volatile boolean swap = false;
       long starttime;

       public DelayedSwap(int index, long starttime) {
           super();
           this.index = index;
           this.starttime = starttime;
       }

       private long getDelay() {
           return (swap ? starttime + (2*COUNT - index) * 100 :
               starttime + index * 100) - System.currentTimeMillis();
       }


       public String toString()
       {
           return index + " swapped " + swap + " delay " + getDelay();
       }

       @Override
       public long getDelay(TimeUnit unit) {
           return unit.convert(getDelay(), TimeUnit.MILLISECONDS);
       }

       @Override
       public int compareTo(Delayed delayed) {
           if (delayed == this)
               return 0;

           return (int)(getDelay(TimeUnit.MILLISECONDS) - delayed.getDelay(TimeUnit.MILLISECONDS));
       }
   }


So to test this I created a method that would create a bunch of the DelayedSwap objects and half way through processing the list switch the flag so altering the order of expiration.

public static void main(String[] args) throws InterruptedException {

       long start = System.currentTimeMillis();
       final List delayed = new ArrayList();
       for (int i = 1; i < COUNT; i++) {
           delayed.add(new DelayedSwap(i, start));
       }

       final DelayQueue dq = new DelayQueue();
       dq.addAll(delayed);

       new Thread(new Runnable() {

           @Override
           public void run() {
               try {
                   TimeUnit.SECONDS.sleep(5);
               } catch (InterruptedException e) {
               }
               for (DelayedSwap d : delayed) {
                   d.swap = true;
               }
           }
       }).start();

       while (!dq.isEmpty()) {
           System.out.println(dq.take());
       }

   }

So what I was expecting was the elements 1-50 ish written out in the correct order but instead after the swap over the elements are coming out in an arbitrary order quite far away from the request delay time.

1 swapped false delay -19
2 swapped false delay -4
3 swapped false delay -4
4 swapped false delay -4
5 swapped false delay -4
6 swapped false delay -4
7 swapped false delay -4
8 swapped false delay -4
9 swapped false delay -4
10 swapped false delay -4
11 swapped false delay -4
12 swapped false delay -4
13 swapped false delay -4
14 swapped false delay -4
15 swapped false delay -4
16 swapped false delay -4
17 swapped false delay -4
18 swapped false delay -4
19 swapped false delay -4
20 swapped false delay -4
21 swapped false delay -4
22 swapped false delay -4
23 swapped false delay -4
24 swapped false delay -4
25 swapped false delay -4
26 swapped false delay -4
27 swapped false delay -4
28 swapped false delay -4
29 swapped false delay -4
30 swapped false delay -4
31 swapped false delay -4
32 swapped false delay -4
33 swapped false delay -4
34 swapped false delay -4
35 swapped false delay -4
36 swapped false delay -4
37 swapped false delay -4
38 swapped false delay -4
39 swapped false delay -5
40 swapped false delay -4
41 swapped false delay -4
42 swapped false delay -5
43 swapped false delay -4
44 swapped false delay -5
45 swapped false delay -5
46 swapped false delay -5
47 swapped false delay -5
48 swapped false delay -5
49 swapped false delay -5
50 swapped false delay -5
51 swapped true delay -6
94 swapped true delay -4306
96 swapped true delay -4506
87 swapped true delay -3606
91 swapped true delay -4006
97 swapped true delay -4606
95 swapped true delay -4406
98 swapped true delay -4706
92 swapped true delay -4106
82 swapped true delay -3106
80 swapped true delay -2906
90 swapped true delay -3906
93 swapped true delay -4206
74 swapped true delay -2306
99 swapped true delay -4806
70 swapped true delay -1906
69 swapped true delay -1806
66 swapped true delay -1506
83 swapped true delay -3206
62 swapped true delay -1107
61 swapped true delay -1007
58 swapped true delay -707
71 swapped true delay -2007
89 swapped true delay -3807
85 swapped true delay -3407
78 swapped true delay -2707
86 swapped true delay -3507
81 swapped true delay -3007
88 swapped true delay -3707
84 swapped true delay -3307
79 swapped true delay -2807
76 swapped true delay -2507
72 swapped true delay -2107
68 swapped true delay -1707
65 swapped true delay -1407
60 swapped true delay -907
57 swapped true delay -608
55 swapped true delay -408
75 swapped true delay -2408
77 swapped true delay -2608
73 swapped true delay -2208
63 swapped true delay -1208
67 swapped true delay -1608
64 swapped true delay -1308
59 swapped true delay -808
56 swapped true delay -508
54 swapped true delay -308
53 swapped true delay -208
52 swapped true delay -108
Process exited with exit code 0.

So the trick is when you know you are going to modify the delay is to remove and then re-add the element to the queue.

// Replacement swap loop
    for (DelayedSwap d : delayed) {
        if (dq.remove(d))
        {
            d.swap = true;
            dq.add(d);
        }
    }

This run produces a more sensible set of results:

1 swapped false delay -4
2 swapped false delay -8
3 swapped false delay -14
4 swapped false delay -8
5 swapped false delay -4
6 swapped false delay -4
7 swapped false delay -4
8 swapped false delay -4
9 swapped false delay -4
10 swapped false delay -4
11 swapped false delay -4
12 swapped false delay -4
13 swapped false delay -4
14 swapped false delay -4
15 swapped false delay -4
16 swapped false delay -4
17 swapped false delay -4
18 swapped false delay -8
19 swapped false delay -4
20 swapped false delay -4
21 swapped false delay -4
22 swapped false delay -4
23 swapped false delay -4
24 swapped false delay -4
25 swapped false delay -4
26 swapped false delay -4
27 swapped false delay -4
28 swapped false delay -4
29 swapped false delay -4
30 swapped false delay -4
31 swapped false delay -4
32 swapped false delay -4
33 swapped false delay -4
34 swapped false delay -4
35 swapped false delay -4
36 swapped false delay -4
37 swapped false delay -4
38 swapped false delay -4
39 swapped false delay -5
40 swapped false delay -5
41 swapped false delay -5
42 swapped false delay -4
43 swapped false delay -4
44 swapped false delay -5
45 swapped false delay -5
46 swapped false delay -5
47 swapped false delay -5
48 swapped false delay -5
49 swapped false delay -5
50 swapped false delay -5
99 swapped true delay -5
98 swapped true delay -5
97 swapped true delay -11
96 swapped true delay -1
95 swapped true delay -5
94 swapped true delay -9
93 swapped true delay -5
92 swapped true delay -5
91 swapped true delay -5
90 swapped true delay -5
89 swapped true delay -5
88 swapped true delay -5
87 swapped true delay -5
86 swapped true delay -5
85 swapped true delay -5
84 swapped true delay -5
83 swapped true delay -5
82 swapped true delay -5
81 swapped true delay -5
80 swapped true delay -5
79 swapped true delay -5
78 swapped true delay -5
77 swapped true delay -5
76 swapped true delay -5
75 swapped true delay -5
74 swapped true delay -5
73 swapped true delay -5
72 swapped true delay -6
71 swapped true delay -5
70 swapped true delay -5
69 swapped true delay -5
68 swapped true delay -5
67 swapped true delay -5
66 swapped true delay -5
65 swapped true delay -5
64 swapped true delay -5
63 swapped true delay -6
62 swapped true delay -5
61 swapped true delay -6
60 swapped true delay -6
59 swapped true delay -6
58 swapped true delay -6
57 swapped true delay -6
56 swapped true delay -6
55 swapped true delay -6
54 swapped true delay -6
53 swapped true delay -6
52 swapped true delay -6
51 swapped true delay -6
Process exited with exit code 0.

I don't think this is a bug in the object itself, as you wouldn't expect a HashTable to orders it's self when the key changes, but I was a little bit surprise by the behaviour.