
<?xml version="1.0" encoding="UTF-8"?> <syn:definitions xmlns:syn="http://ws.apache.org/ns/synapse"> <syn:registry provider="org.wso2.carbon.mediation.registry.WSO2Registry"> <syn:parameter name="cachableDuration">15000</syn:parameter> </syn:registry> <syn:proxy name="test" transports="https http" startOnLoad="true" trace="disable"> <syn:target> <syn:inSequence> <syn:send/> </syn:inSequence> <syn:outSequence> <syn:send/> </syn:outSequence> </syn:target> </syn:proxy> <syn:sequence name="main"> <syn:in> <syn:log level="full"/> <syn:filter source="get-property('To')" regex="http://localhost:9000.*"> <syn:send/> </syn:filter> </syn:in> <syn:out> <syn:send/> </syn:out> </syn:sequence> <syn:sequence name="fault"> <syn:log/> </syn:sequence> </syn:definitions>Now, we need to apply security to the proxy service.
package org.apache.ws.axis2; import java.util.Properties; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMFactory; import org.apache.axiom.om.OMNamespace; import org.apache.axiom.om.impl.builder.StAXOMBuilder; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.client.ServiceClient; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.context.ConfigurationContextFactory; import org.apache.neethi.Policy; import org.apache.neethi.PolicyEngine; import org.apache.rahas.RahasConstants; import org.apache.rahas.Token; import org.apache.rahas.TokenStorage; import org.apache.rahas.TrustUtil; import org.apache.rahas.client.STSClient; import org.apache.rampart.RampartMessageData; import org.apache.rampart.policy.model.RampartConfig; import org.apache.rampart.policy.model.CryptoConfig; import org.apache.ws.secpolicy.Constants; import org.opensaml.XML; public class IdentitySTSClient { /** * @param args */ final static String RELYING_PARTY_SERVICE_EPR = "http://192.168.1.2:8280/services/echo"; final static String ESB_TRANS_EPR = "http://192.168.1.2:8280/services/test"; final static String STS_EPR = "https://localhost:9443/services/wso2carbon-sts"; /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { ConfigurationContext confContext = null; Policy stsPolicy = null; STSClient stsClient = null; Policy servicePolicy = null; Token responseToken = null; String trustStore = null; // You need to import the Identity Server, public certificate to this key store. // By default it's there - if you use wso2carbon.jks from [ESB_HOME]\resources\security trustStore = "wso2carbon.jks"; // We are accessing STS over HTTPS - so need to set trustStore parameters. System.setProperty("javax.net.ssl.trustStore", trustStore); System.setProperty("javax.net.ssl.trustStorePassword", "wso2carbon"); // Create configuration context - you will have Rampart module engaged in the // client.axis2.xml confContext = ConfigurationContextFactory.createConfigurationContextFromFileSystem("repo", "repo/conf/client.axis2.xml"); stsClient = new STSClient(confContext); stsClient.setRstTemplate(getRSTTemplate()); stsClient.setAction(RahasConstants.WST_NS_05_02 + RahasConstants.RST_ACTION_SCT); // This is the security policy we applied to Identity Server STS. // You can see it by https://[IDENTITY_SERVER]/services/wso2carbon-sts?wsdl stsPolicy = loadSTSPolicy("sts.policy.xml"); // This is the security of the relying party web service. // This policy will accept a security token issued from Identity Server STS servicePolicy = loadServicePolicy("service.policy.xml"); responseToken = stsClient.requestSecurityToken(servicePolicy, STS_EPR, stsPolicy, RELYING_PARTY_SERVICE_EPR); System.out.println(responseToken.getToken()); TokenStorage store = TrustUtil.getTokenStore(confContext); store.add(responseToken); ServiceClient client = new ServiceClient(confContext, null); Options options = new Options(); options.setAction("urn:echoString"); options.setTo(new EndpointReference(RELYING_PARTY_SERVICE_EPR)); options.setProperty(org.apache.axis2.Constants.Configuration.TRANSPORT_URL, ESB_TRANS_EPR); options.setProperty(RampartMessageData.KEY_RAMPART_POLICY,servicePolicy); options.setProperty(RampartMessageData.KEY_CUSTOM_ISSUED_TOKEN, responseToken.getId()); client.setOptions(options); client.engageModule("addressing"); client.engageModule("rampart"); OMElement response = client.sendReceive(getPayload("Hello world1")); System.out.println("Response : " + response); } private static Policy loadSTSPolicy(String xmlPath) throws Exception { StAXOMBuilder builder = null; Policy policy = null; RampartConfig rc = null; builder = new StAXOMBuilder(xmlPath); policy = PolicyEngine.getPolicy(builder.getDocumentElement()); rc = new RampartConfig(); rc.setUser("admin"); // You need to have password call-back class to provide the user password rc.setPwCbClass(PWCBHandler.class.getName()); policy.addAssertion(rc); return policy; } private static Policy loadServicePolicy(String xmlPath) throws Exception { StAXOMBuilder builder = null; Policy policy = null; RampartConfig rc = null; CryptoConfig sigCryptoConfig = null; String keystore = null; Properties merlinProp = null; CryptoConfig encrCryptoConfig = null; builder = new StAXOMBuilder(xmlPath); policy = PolicyEngine.getPolicy(builder.getDocumentElement()); rc = new RampartConfig(); rc.setUser("wso2carbon"); rc.setEncryptionUser("wso2carbon"); // You need to have password call-back class to provide the user password rc.setPwCbClass(PWCBHandler.class.getName()); keystore = "wso2carbon.jks"; merlinProp = new Properties(); merlinProp.put("org.apache.ws.security.crypto.merlin.keystore.type","JKS"); merlinProp.put("org.apache.ws.security.crypto.merlin.file", keystore); merlinProp.put("org.apache.ws.security.crypto.merlin.keystore.password","wso2carbon"); sigCryptoConfig = new CryptoConfig(); sigCryptoConfig.setProvider("org.apache.ws.security.components.crypto.Merlin"); sigCryptoConfig.setProp(merlinProp); encrCryptoConfig = new CryptoConfig(); encrCryptoConfig.setProvider("org.apache.ws.security.components.crypto.Merlin"); encrCryptoConfig.setProp(merlinProp); rc.setSigCryptoConfig(sigCryptoConfig); rc.setEncrCryptoConfig(encrCryptoConfig); policy.addAssertion(rc); return policy; } private static OMElement getRSTTemplate() throws Exception { OMFactory fac = OMAbstractFactory.getOMFactory(); OMElement elem = fac.createOMElement(Constants.RST_TEMPLATE); TrustUtil.createTokenTypeElement(RahasConstants.VERSION_05_02, elem).setText(XML.SAML_NS); TrustUtil.createKeyTypeElement(RahasConstants.VERSION_05_02, elem,RahasConstants.KEY_TYPE_SYMM_KEY); TrustUtil.createKeySizeElement(RahasConstants.VERSION_05_02, elem, 256); return elem; } private static OMElement getPayload(String value) { OMFactory factory = null; OMNamespace ns = null; OMElement elem = null; OMElement childElem = null; factory = OMAbstractFactory.getOMFactory(); ns = factory.createOMNamespace("http://echo.services.core.carbon.wso2.org", "ns1"); elem = factory.createOMElement("echoString", ns); childElem = factory.createOMElement("in", null); childElem.setText(value); elem.addChild(childElem); return elem; } }
package org.apache.ws.axis2; import org.apache.ws.security.WSPasswordCallback; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; public class PWCBHandler implements CallbackHandler { public void handle(Callback[] callbacks) throws UnsupportedCallbackException { WSPasswordCallback cb = (WSPasswordCallback) callbacks[0]; if ("admin".equals(cb.getIdentifier())) { cb.setPassword("admin"); } else { cb.setPassword("wso2carbon"); } } }
package org.apache.ws.axis2; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMFactory; import org.apache.axiom.om.OMNamespace; import org.apache.axiom.om.impl.builder.StAXOMBuilder; import org.apache.axis2.Constants; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.client.ServiceClient; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.context.ConfigurationContextFactory; import org.apache.neethi.Policy; import org.apache.neethi.PolicyEngine; import org.apache.rampart.RampartMessageData; public class TestClient { final static String ADDR_URL = "http://192.168.1.2:8280/services/echo"; final static String TRANS_URL = "https://192.168.1.2:8243/services/test"; public static void main(String[] args) throws Exception { ServiceClient client = null; Options options = null; OMElement response = null; ConfigurationContext context = null; String trustStore = null; // You need to import the ESBs public certificate to this key store. trustStore = "mykeystore.jks"; // We are accessing ESB over HTTPS - so need to set trustStore parameters. System.setProperty("javax.net.ssl.trustStore", trustStore); // Password of mykeystore.jks System.setProperty("javax.net.ssl.trustStorePassword", "wso2carbon"); // Create configuration context - you will have Rampart module engaged in the client.axis2.xml context = ConfigurationContextFactory.createConfigurationContextFromFileSystem("repo","repo/conf/client.axis2.xml"); // This is the security policy of the proxy service applied UT. StAXOMBuilder builder = new StAXOMBuilder("policy.xml"); Policy policy = PolicyEngine.getPolicy(builder.getDocumentElement()); context = ConfigurationContextFactory.createConfigurationContextFromFileSystem("repo","repo/conf/client.axis2.xml"); client = new ServiceClient(context, null); options = new Options(); options.setAction("urn:echoString"); // This is the addressing URL pointing to the echo service deployed in ESB options.setTo(new EndpointReference(ADDR_URL)); // To the ESB, the proxy service options.setUserName("admin"); options.setPassword("admin"); // TRANS_URL points to proxy service options.setProperty(Constants.Configuration.TRANSPORT_URL, TRANS_URL); options.setProperty(RampartMessageData.KEY_RAMPART_POLICY, policy); client.setOptions(options); client.engageModule("addressing"); client.engageModule("rampart"); response = client.sendReceive(getPayload("Hello world")); System.out.println(response); } private static OMElement getPayload(String value) { OMFactory factory = null; OMNamespace ns = null; OMElement elem = null; OMElement childElem = null; factory = OMAbstractFactory.getOMFactory(); ns = factory.createOMNamespace("http://echo.services.core.carbon.wso2.org", "ns1"); elem = factory.createOMElement("echoString", ns); childElem = factory.createOMElement("in", null); childElem.setText(value); elem.addChild(childElem); return elem; } }
<Request xmlns="urn:oasis:names:tc:xacml:2.0:context:schema:os" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <Subject> <Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string"> <AttributeValue>admin</AttributeValue> </Attribute> <Attribute AttributeId="group" DataType="http://www.w3.org/2001/XMLSchema#string"> <AttributeValue>admin</AttributeValue> </Attribute> </Subject> <Resource> <Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string"> <AttributeValue>http://localhost:8280/services/echo/echoString</AttributeValue> </Attribute> </Resource> <Action> <Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"> <AttributeValue>read</AttributeValue> </Attribute> </Action> <Environment/> </Request>In plain English above request says, 'admin' user who belongs to the group 'admin' - trying to access the echoString operation of http://localhost:8280/services/echo service.
<Resources> <Resource> <ResourceMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-regexp-match"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">http://localhost:8280/services/echo/ <ResourceAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ResourceMatch> </Resource> </Resources>Here in this policy we use the function:string-regexp-match to validate the service name + operation name combination. You can modify it to suit your own requirement.
<Condition> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-is-in"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">admin</AttributeValue> <SubjectAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string" SubjectCategory="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"/> </Apply> </Condition>
<Condition> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-is-in"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">admin</AttributeValue> <SubjectAttributeDesignator AttributeId="group" DataType="http://www.w3.org/2001/XMLSchema#string"/> </Apply> </Condition>Here we validate user 'admin' or any user in the group 'admin'.
package org.apache.ws.axis2; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMFactory; import org.apache.axiom.om.impl.builder.StAXOMBuilder; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.context.ConfigurationContextFactory; import org.apache.neethi.Policy; import org.apache.neethi.PolicyEngine; import org.apache.rahas.RahasConstants; import org.apache.rahas.Token; import org.apache.rahas.TrustUtil; import org.apache.rahas.client.STSClient; import org.apache.rampart.policy.model.RampartConfig; import org.apache.ws.secpolicy.Constants; import org.opensaml.XML; public class IdentitySTSClient { /** * @param args */ final static String RELYING_PARTY_SERVICE_EPR = "http://192.168.1.2:8280/services/echo"; final static String STS_EPR = "https://localhost:9443/services/wso2carbon-sts"; /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { ConfigurationContext confContext = null; Policy stsPolicy = null; STSClient stsClient = null; Policy servicePolicy = null; Token responseToken = null; String trustStore = null; // You need to import the Identity Server, public certificate to this key store. trustStore = "clientkeystore.jks"; // We are accessing STS over HTTPS - so need to set trustStore parameters. System.setProperty("javax.net.ssl.trustStore", trustStore); System.setProperty("javax.net.ssl.trustStorePassword", "wso2carbon"); // Create configuration context - you will have Rampart module engaged in the client.axis2.xml confContext = ConfigurationContextFactory.createConfigurationContextFromFileSystem("repo","repo/conf/client.axis2.xml"); stsClient = new STSClient(confContext); stsClient.setRstTemplate(getRSTTemplate()); stsClient.setAction(RahasConstants.WST_NS_05_02 + RahasConstants.RST_ACTION_SCT); // This is the security policy we applied to Identity Server STS. // You can see it by https://[IDENTITY_SERVER]/services/wso2carbon-sts?wsdl stsPolicy = loadPolicy("sts.policy.xml"); // This is the security of the relying party web service. // This policy will accept a security token issued from Identity Server STS servicePolicy = loadPolicy("service.policy.xml"); responseToken = stsClient.requestSecurityToken(servicePolicy, STS_EPR, stsPolicy, RELYING_PARTY_SERVICE_EPR); System.out.println(responseToken.getToken()); } private static Policy loadPolicy(String xmlPath) throws Exception { StAXOMBuilder builder = null; Policy policy = null; RampartConfig rc = null; builder = new StAXOMBuilder(xmlPath); policy = PolicyEngine.getPolicy(builder.getDocumentElement()); rc = new RampartConfig(); rc.setUser("admin"); // You need to have password call-back class to provide the user password rc.setPwCbClass(PWCBHandler.class.getName()); policy.addAssertion(rc); return policy; } private static OMElement getRSTTemplate() throws Exception { OMFactory fac = OMAbstractFactory.getOMFactory(); OMElement elem = fac.createOMElement(Constants.RST_TEMPLATE); TrustUtil.createTokenTypeElement(RahasConstants.VERSION_05_02, elem).setText(XML.SAML_NS); TrustUtil.createKeyTypeElement(RahasConstants.VERSION_05_02, elem, RahasConstants.KEY_TYPE_SYMM_KEY); TrustUtil.createKeySizeElement(RahasConstants.VERSION_05_02, elem, 256); return elem; } }