MuleSoft Custom Policies

MuleSoft Custom Policies

A Custom Policy is a MuleSoft policy you can implement in case you need to extend the out-of-the-box MuleSoft policies or you need to define new functionality for your API management strategy.

Example Use Case: Stripe

Stripe is a technology company that builds economic infrastructure for the internet. Businesses of every size from new startups to public companies use Stripe to accept payments and manage businesses online.

A Stripe webhook is intended to listen for events on your Stripe account so your integration can automatically trigger reactions.

Stripe uses webhooks to notify your application when an event happens in your account. Webhooks are particularly useful for asynchronous events like when a customer’s bank confirms a payment, a customer disputes a charge, a recurring payment succeeds, or when collecting subscription payments.

Stripe Signature Validation

Stripe can optionally sign the webhook events it sends to your endpoints by including a signature in each event’s Stripe-Signature header. This allows you to verify that the events were sent by Stripe, not by a third party.

Stripe provides a set of libraries you can use to validate the signatures, but you are also able to validate the signatures using a manual process. This is where a MuleSoft Custom Policy makes sense.

In summary, the steps to validate Stripe Signatures are:

  1. Extract the timestamp and signatures from the header
  2. Prepare the signed_payload string
  3. Determine the expected signature
  4. Compare the signatures

You can check more details about how to validate Stripe Signatures in the official documentation .

Steps to create a Custom Policy

It is not hard to develop a Custom Policy, in fact, you only need to:

  1. Develop the policy
  2. Package the policy
  3. Push the policy to Anypoint Exchange
  4. Use the policy through API Manager

Develop the policy

Maven Setup

The first step is to configure Maven through the settings.xml file. To do that, you’ll need to open the settings.xml file that is typically found under the $USER_HOME/.m2 directory.

The servers section is used to store usernames and passwords for the repositories. There are repositories that are public and others that are private. For example, the Mule Enterprise Repository is not publicly available and requires an active Mule license.

You need to configure credentials for two repositories in the servers section of the settings.xml file:

  • Anypoint Exchange credentials. This is used to push the Custom Policy to your Anypoint Exchange.
  • MuleSoft Enterprise credentials. This is used to connect to the private MuleSoft Enterprise Repository. You can get your credentials creating a ticket in MuleSoft Support .

Here is an example of the settings.xml servers section content to configure these credentials:

<servers
	<server>
? ? ? ? <id>MuleRepository</id>
? ? ? ? <username>XXXXXXX</username>
? ? ? ? <password>XXXXXXX</password>
? ? </server>
	 <server>
 ? ? ? <id>exchange-server</id>
 ? ? ? <username>XXXXXXX</username>
 ? ? ? <password>XXXXXXX</password>
 ? ? </server>
? </servers>        

The profiles section is used to configure the remote repositories. In order to create a custom policy, you need to configure two remote repositories:

  • Mule Master Repository (public)
  • Mule Nexus Repository (private)

Here is an example of the settings.xml profiles section content to add these remote repositories:

<profiles
? ? ? <profile>
 ? ? ? ? <id>archetype-repository</id>
 ? ? ? ? <repositories>
? ? ? ? ? ? <repository>
 ? ? ? ? ? ? ? <id>archetype</id>
 ? ? ? ? ? ? ? <name>Mule Repository</name>
 ? ? ? ? ? ? ? <url>https://repository-master.mulesoft.org/nexus/content/repositories/public</url>
 ? ? ? ? ? ? ? <releases>
? ? ? ? ? ? ? ? ? <enabled>true</enabled>
? ? ? ? ? ? ? ? ? <checksumPolicy>fail</checksumPolicy>
 ? ? ? ? ? ? ? </releases>
 ? ? ? ? ? ? ? <snapshots>
? ? ? ? ? ? ? ? ? <enabled>true</enabled>
? ? ? ? ? ? ? ? ? <checksumPolicy>warn</checksumPolicy>
 ? ? ? ? ? ? ? </snapshots>
? ? ? ? ? ? </repository>
 ? ? ? ? </repositories>
? ? ? </profile>
? ? ? <profile>
 ? ? ? ? <id>Mule</id>
 ? ? ? ? <activation>
? ? ? ? ? ? <activeByDefault>true</activeByDefault>
 ? ? ? ? </activation>
 ? ? ? ? <repositories>
? ? ? ? ? ? <repository>
 ? ? ? ? ? ? ? <id>MuleRepository</id>
 ? ? ? ? ? ? ? <name>MuleRepository</name>
 ? ? ? ? ? ? ? <url>https://repository.mulesoft.org/nexus-ee/content/repositories/releases-ee/</url>
 ? ? ? ? ? ? ? <layout>default</layout>
 ? ? ? ? ? ? ? <releases>
? ? ? ? ? ? ? ? ? <enabled>true</enabled>
 ? ? ? ? ? ? ? </releases>
 ? ? ? ? ? ? ? <snapshots>
? ? ? ? ? ? ? ? ? <enabled>true</enabled>
 ? ? ? ? ? ? ? </snapshots>
? ? ? ? ? ? </repository>
 ? ? ? ? </repositories>
? ? ? </profile>
 ? </profiles>        

Creating policy project using Maven

Once you have your Maven setup ready, you will need to create the initial project structure using the Maven archetype for MuleSoft Custom Policies. In order to do that, you will need to create a new folder in your file system and run the Maven command to create the project.

Open the command line and navigate to the folder you created before and execute the following Maven command:

mvn -Parchetype-repository archetype:generate 
-DarchetypeGroupId=org.mule.tools \
-DarchetypeArtifactId=api-gateway-custom-policy-archetype \
-DarchetypeVersion=1.2.0 \
-DgroupId=${orgId} \
-DartifactId=${policyName} \
-Dversion=1.0.0-SNAPSHOT \
-Dpackage=mule-policy\        

Replace the ${orgId} with the Organization Id from Management Center at Anypoint Platform. If you do not know how to get your Org ID, please follow these steps .

Replace the ${policyName} with the name of your new policy. Let’s say: stripe-signature-validation and then run the command.

As this command is going to run in an interactive mode, it will ask for confirmation of all the info you provided as inputs for the Maven command. Just type ‘Y’ and it will be confirmed. The Maven command will start the build process and will create the initial version of the custom policy code.

No alt text provided for this image
No alt text provided for this image

Now you have the initial version of the code, you can import it to Anypoint Studio and start implementing the logic for the custom policy. Launch Anypoint Studio and click on Import Project > Anypoint Studio From File System > Next > Select the Project Root (where the code was generated) > Finish.

No alt text provided for this image



No alt text provided for this image















Code the policy logic

Now you have the project in Anypoint Studio, you can start coding the policy logic. As you can see, the archetype will generate the following files:

  • template.xml. The actual logic for the policy and MuleSoft configuration will live here. This is basically the implementation file.
  • ${policy-name}.yam. It renders the policy configuration UI at API Manager. You may add any configurable parameter to your policy in this file. API Manager will ask for those parameters in the UI (when you are applying the policy).
  • pom.xml. Main Maven file.
  • mule-artifact.json. Used by the mule-maven plugin.

No alt text provided for this image

Unfortunately Anypoint Studio does not have a UI to develop the logic policy, so you need to add the policy logic in the XML view. Pro-tip: you can create the policy logic in a regular MuleSoft application project and then copy the XML from the configuration file and paste it in the policy XML file. That way you have the Visual Editor available.

To implement the Stripe Signature Validation, we implemented the following logic:

  • Add the tolerance parameter in the YAML file to protect against timing attacks. That value must be injected when applying the policy.
  • Retrieve the information of the webhook id in order to retrieve its secret to sign the message. This parameter could be included in the HTTP Request headers. I used DataWeave to capture this value from the headers and store it into a variable.
  • Retrieve the webhook secret. There are many options to do this. You can use an external service that handles the webhook secrets. The main idea here is once you’ve identified the consumer, you need to retrieve its secret.
  • Capture the Stripe-Signature Header that is coming from Stripe in the HTTP Request headers using DataWeave.
  • Extract the timestamp and signature using DataWeave. Split the header values by comma (,).
  • Once you have the timestamp (t) and signature (v1), start validating the tolerance. Remember that the tolerance is coming from the Policy input parameters (configurable when applying the policy).
  • First, calculate the difference between now (when you are enforcing the policy and receiving the request) and the timestamp (t, when the request is sent).
  • If the difference is not within the tolerance, you must reject the request. I’m using an Is true validator.
  • The next step is to concatenate t + “.” + JSON body (as String). In order to do this, you will need to extract the string representation of the request (body) using the ^raw DataWeave selector. Notice that the “\r” character must be removed, otherwise the calculated signature will be different.
  • Once you have everything ready, then concatenate the values to calculate the signed payload:
  • Next, determine the expected signature using a very cool function within the Crypto DataWeave module: HMACWith. This will compute an HMAC hash, then will transform the result into a lowercase, hexadecimal string. As input parameters you will use the webhook secret and the signed payload.
  • At this point, you have everything you need. You can compare (validate) if the signature from the Stripe-Signature header is equal to the expected signature you calculated in the previous step. If they are not equal, you can reject the message. I’m using an Is true validator.

Package the policy

You are almost done!

You are almost done! You only need to package and deploy the policy before starting testing it. Maven will help (again) to package the policy. You just need to run the following command:

Push the policy to Anypoint Exchange

Then just push the policy to Anypoint Exchange. Maven command? mvn clean deploy

After a while, Maven will package and deploy the policy to Anypoint Exchange. You will see info messages related to the uploading process. After all, you’ll get the BUILD SUCCESS message.

No alt text provided for this image

Your policy is available at Anypoint Exchange and ready to use.





Use the policy to API Manager

Now the policy is ready, you just need to apply it to an existing API using API Manager. In order to do that you need to log in to Anypoint Platform > API Manager > Select the API you want to apply the policy > Policies > Apply New Policy > Filter by Custom category > Select your policy > Click on Configure Policy.

No alt text provided for this image

Finally, configure the policy as needed and click on Apply. The tolerance parameter is being rendered by the property you added in the YAML file. If you want to learn more about the YAML file, just go to the YAML Configuration File documentation.

No alt text provided for this image


There are more resources related to developing custom policies, please visit the MuleSoft official documentation to learn more and… Happy coding!

Author

Leonardo Gonzales, MuleSoft Mentor and MuleSoft Team Lead at SPS

No alt text provided for this image

References




How do I invoke a custom connector from a custom policy? I want to use a custom connector to modify the response message.

回复

要查看或添加评论,请登录

MuleSoft Community的更多文章

社区洞察

其他会员也浏览了