Lets say, we have a backend web service that has been secured with Username Token security policy and user name token must be sent to access it. But your client application (which is not in this domain), would send user name and password in different manner (not in Username token). Therefore client would not be able to talk to the backend server. Assume; we can not do any changes to both the backend web service and the client application. Then we need to do some security protocol transformation by intercepting the message from client to server. Basically you can easily use WSO2 ESB to achieve this task.
There can be three scenarios.
1. Client applications does not send any user/password and It just send a non secured message. ESB needs to send a user name token to backend service. There is a pre-defined user/password that has been given to ESB. Then ESB can read user/password from some configuration and create the user name token using WS-Security policy.
2. Client applications send user/password using different security mechanisms (Say in Basic authentication header). ESB needs to convert it to a user name token and send it to the backend service. Therefore ESB can read the incoming message and extract user/password and then create the user name token using WS-Security policy.
3. Client applications send only the user identifier using different security mechanisms (Say in SAML/JWT token). ESB needs to find the user’s password and convert it to a user name token and send it to the backend service. Therefore ESB can read the incoming message and extract the user identifier. Then It can call external sources to find the password for given users and create the user name token using WS-Security policy.
Therefore, to achieve all above three scenarios, We need a way to set the user/password in to the user name token policy in a dynamic manner. This can be easily done by writing a class mediator for WSO2 ESB. Please find more details on writing a class mediator from here. Source of the custom mediator, that i have written for this purpose can be found here. I urge you to go through it.. It is really simple and you can understand it clearly.
Let see how we can configure Username tokens for outbound messages.
Step 1. Deploy custom mediator. You can find the custom mediator jar file from target directory. Please copy org.soasecurity.wssecurity.ut.mediator-1.0.0.jar file in to <ESB_HOME>/repository/components/lib directory and restart the server.
Step 2. Upload Username Token security policy in to the ESB Registry location.
If you need to create a Username Token with plain text password, Please use this WS-Security policy.
If you want to create Username Token with hash password, Please use this WS-Security policy.
Custom mediator currently has four properties…
1. userNameProperty — > This is the Synapse message context property name that user name would be read by the custom mediator.
2. passwordProperty –> This is the Synapse message context property name that password would be read by the custom mediator.
As an example, if you think about scenario 2, Incoming message would contain the user/password and the message processor that reads the incoming message, may extract and set the user/password in to synapse message context properties. If you want to read them using custom mediator, you can configure above two properties with correct property names.
If username is contained in the incoming HTTP Basic Auth header, you must set value of “userNameProperty” and “passwordProperty” property as “BASIC_AUTH”
3. dataSourceName –> Datasource name that can be configured in the master-datasources.xml file. This can be used to retrieve password from external sources.
4. passwordSQLQuery –> SQL query that can be used to extract password from above configured data source.
All four properties are optional ones. You may not be much worry about these properties. But it is better if you can understand the custom mediator logic.. Because then you can write your own mediator according to your use case.
Step 5. You can create proxy service with above endpoint and custom mediator. Synapse configuration of the proxy service would be as follows.
<proxy name="UTBEPolicy" transports="https http" startOnLoad="true" trace="disable"> <description/> <target> <inSequence> <class name="org.soasecurity.wssecurity.ut.mediator.UTTokenBuilder"> <property name="passwordSQLQuery" value=""/> <property name="userNameProperty" value=""/> <property name="passwordProperty" value=""/> <property name="dataSourceName" value=""/> </class> <send> <endpoint> <address uri="https://localhost:9443/services/echo"> <enableSec policy="conf:/policy/UTHashPasswordPolicy.xml"/> </address> </endpoint> </send> </inSequence> <outSequence> <send/> </outSequence> </target> </proxy>
Step 6. Testing.
If you does not have any datasource or incoming messages with user/password. you can still test this by configuring user/password in the synapse configuration. You can add following two synapse configuration properties before the custom mediator configuration in the in-sequence. These two properties have been configured the user/password in a way that they can be read from custom mediator.
<property name="username" value="Bob" scope="axis2" type="STRING"/> <property name="password" value="bobPass" scope="axis2" type="STRING"/>
Once you send a message to proxy service, It would create message to backend service that is secured with user name token. Username token would contain the user/password that is configured in synapse configuration. Full Synpase configuration for testing proxy can be found here