WSO2: Configuring a proxy to a service with authentication by login and password

Task


There is an application that can request data using a specific protocol and there is a service that can send data, but using a different protocol and requires authorization by login and password.
The application does not have the credentials necessary to access the service. You need to make friends the application and service.

Decision


Use bus: WSO2 Enterprise Service Bus , on which to configure the proxy service.

We use WSO2 ESB version 4.7.0.

Creating Policies

Since the target service is protected by the WS-Security standard, we will configure access to it to the fullest extent of the standard.
Policies are created as resources in the local repository, in the interface: Manage - Service Bus - Local Entries - Add Local Entries - Add In-lined XML Entry.

Outgoing Policies

Here and in the future, names can be given arbitrary, but I will focus on them, because through them all artifacts will be linked into a single whole. We
indicate the name: service-policy We
specify the policy:

MyUsernames.e.r.PasswordCallbackHandler

The main part of this policy is to specify the username of the target service and the class, which in our case will simply substitute the necessary password, the serPasswordCallBackHandler class :

package s.e.r;
import org.apache.ws.security.WSPasswordCallback;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.IOException;
public class PasswordCallBackHandler implements CallbackHandler
{
    private static final String PASSWORD = "MyPassword";
    @Override
    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
    {
        for (Callback callback : callbacks)
        {
            if (callback instanceof WSPasswordCallback)
            {
                WSPasswordCallback pc = (WSPasswordCallback) callback;
                if (pc.getUsage() == WSPasswordCallback.USERNAME_TOKEN_UNKNOWN)
                {
                    if (pc.getPassword().equals(PASSWORD))
                        return;
                    throw new UnsupportedCallbackException(callback, "Check failed");
                }
                pc.setPassword(PASSWORD);
            } else
            {
                throw new UnsupportedCallbackException(callback, "Unrecognized Callback");
            }
        }
    }
}


We pack in jar and put in WSO2_HOME / repository / components / lib /.
Restart WSO2.

Inbox Policy

Specify the name: empty-policy .
Specify the policy:



Create an Address Endpoint

Specify the name: my-endpoint .
We indicate the address of the service.
In the additional options, we note the use of WS-Security and specify the policies for outgoing and incoming messages created earlier.
Endpoint source:



Create an XSLT message transformation

XSLT transformations are created in the same place as the politicians: Manage - Service Bus - Local Entries - Add Local Entries - Add In-lined XML Entry.

Convert Incoming Message

We need to bring the request of our application to a view that the service understands:
Specify the name: in-xslt
Specify the transformation:



Convert to Outgoing Message

We need to bring the response of the service to a form that is understandable for the application. The step is identical to the step for the incoming message, only the name: out-xslt .

Create a Proxy Service

In the UI: Manage - Service - Add - Proxy Service - Custom Proxy We
specify the name: external-service . By this name your service will be available on the bus, for example: localhost : 8280 / services / external-service.
In our case, uncheck the https protocol.
Next, switch to source mode (switch to source view) and bring the contents to approximately the following:



There are two sequences for the incoming and outgoing messages, both start with the appropriate conversion and then send the message in the right direction.

Done!

Additionally



To monitor what our proxy messages turn into, used fiddler

Because I did not find how to configure and where to watch the final messages.
More about fiddler :


The proxy forwards the Action header that came from the application, and the service swears?

Add mediators to the proxy service sequence, delete the Action header:



Does the proxy return data in incorrect encoding?

Specify the encoding in which we return the message:



The response of the service consists of several parts?

For instance:



WSO2, by default, considers that the answer should consist of one part, therefore they pass on the conversion what is on the way: s11: Body / child :: * [position () = 1] | s12: Body / child :: * [position () = 1], as a result we can transform only the first part, to fix this we change the call of the converter in the service:



... and take this into account in the converter:



Unresolved issues



I had to configure two security policies

There is a feeling that you can do it alone, but with a single policy there was an error that the service response does not contain security headers. But he really does not contain them. To get around this I had to write an empty policy for an answer.

No built-in solution for storing third-party credentials was found

A clumsy solution with a password storage class is an obvious crutch that needs to be replaced with a suitable solution, either built-in or a bicycle.

Total


  • The conversion part did not cause problems, except that the configuration is very much spread over the UI. Of course, you can configure through a single xml in the same UI, but in this case, the configuration will be spread over xml.
  • A fairly high entry threshold for solving the simplest task.
  • The problem is solved!

Also popular now: