Tuesday, August 2, 2016

[WSO2 APIM] How to Retrieve Information about an API call, using a Custom Sequence

Most of the time when you call an API, you need to send user information to the backend service. The usual way to do that is with JWT tokens. There are API Manager docs on how to do that.

But if you want to send just few data values for one or two APIs only, you can write a simple custom sequence and attach it to the APIs.

Here is a sample sequence. Here we're creating 2 transport headers for username and API name, which are to be sent to backend.

 
    <sequence xmlns="http://ws.apache.org/ns/synapse" name="admin--Temp:v1.0.0--In">  
          <property name="UserName" scope="transport" expression="$ctx:api.ut.userName"/>  
          <property name="ApiName" scope="transport" expression="$ctx:API_NAME"/>  
          <log level="custom">  
              <property name="User" expression="$trp:UserName"/>  
              <property name="API" expression="$trp:ApiName"/>  
          </log>  
     </sequence>
  

Here is a list of information you can retrieve in above manner. Sample data for each key is given inside brackets.
  • API_NAME (eg: MyAPI)
  • AM_KEY_TYPE (eg: PRODUCTION)
  • REST_SUB_REQUEST_PATH (eg: /resource/pathparam)
  • SYNAPSE_REST_API (eg: admin--Temp:v1.0.0)
  • SYNAPSE_REST_API_VERSION (eg: 1.0.0)
  • TRANSPORT_IN_NAME (eg: https)
  • REST_API_CONTEXT (eg: /context/1.0.0)
  • API_ELECTED_RESOURCE (eg: /resource/{playerId})
  • REST_FULL_REQUEST_PATH (eg: /context/1.0.0/resource/pathparam)
  • api.ut.HTTP_METHOD (eg: GET)
  • api.ut.application.name (eg: DefaultApplication)
  • api.ut.apiPublisher (eg: admin@carbon.super)
  • api.ut.userId (eg: bhathiya@carbon.super)
  • api.ut.consumerKey (eg: 1IVxJBSKeo793IUYk4EtwvZv8eUa)
  • api.ut.userName (eg: bhathiya@carbon.super)
  • api.ut.application.id (eg: 1)
  • api.ut.hostName (eg: 10.100.0.119)
  • uri.var.playerId (eg: pathparam)

EXTRA:

Following throttling related information can be retrieved in _throttle_out_handler_.xml

  • THROTTLED_OUT_REASON (eg. APPLICATION_LIMIT_EXCEEDED)
  • ERROR_CODE (eg. 900803)
  • ERROR_MESSAGE (eg. Message throttled out)
  • NEXT_ACCESS_TIME (eg. 1523883780000)
  • BLOCKED_REASON (eg. Request blocked as it violates defined blocking conditions)


Thursday, July 28, 2016

How to use log4jdbc with WSO2 products to log JDBC calls

log4jdbc is a nice tool to log JDBC call details of an application. Here are the steps to use it in WSO2 products. Here I'm using WSO2 APIM.

1) Download log4jdbc driver from here, and place it in <API_HOME>/repository/components/lib/ directory.

Note: Make sure to have the JDBC driver corresponding to your database server too in the same directory.

2) In master-datasources.xml,

     i) Change JDBC url like this. (note :log4jdbc: part)
<url>jdbc:log4jdbc:mysql://localhost:3306/AM_DB</url>
     ii) Set JDBC driver class like this.
<driverClassName>net.sf.log4jdbc.DriverSpy</driverClassName>
3)  Add following to log4j.properties file.
log4j.logger.jdbc.sqlonly=INFO
log4j.logger.jdbc.sqltiming=INFO
log4j.logger.jdbc.audit=OFF
log4j.logger.jdbc.resultset=ERROR
log4j.logger.jdbc.connection=ERROR
 
4) Restart the server, and you'll see logs like this.

[2016-07-28 21:25:27,719] INFO - sqltiming SELECT ID, NAME, IS_ENABLED, DISPLAY_NAME FROM IDP_AUTHENTICATOR WHERE IDP_ID = 1
{executed in 5 msec}
[2016-07-28 21:25:27,720] INFO - sqltiming SELECT PROPERTY_KEY, PROPERTY_VALUE, IS_SECRET FROM IDP_AUTHENTICATOR_PROPERTY WHERE AUTHENTICATOR_ID = 1
{executed in 0 msec}



Wednesday, July 6, 2016

[WSO2 IS] User Account Locking/Unlocking with Secondary Userstores

In WSO2 Identity Server, you can lock user accounts when they are created, and unlock later. For this feature to work, in each userstore, a user attribute should be mapped to "http://wso2.org/claims/identity/accountLocked"  claim. In identity server, this claim is already mapped to "accountLock" attribute in embedded LDAP userstore. So you only have to follow below steps to enable "Account locking on creation" feature.

For Primary Userstore


1) Enable Identity Management Listener in <IS_HOME>/repository/conf/identity/identity.xml

<EventListener type="org.wso2.carbon.user.core.listener.UserOperationEventListener" name="org.wso2.carbon.identity.mgt.IdentityMgtEventListener" orderId="50" enable="true"/>

2)  Do the following configurations in the <IS_HOME>/repository/conf/identity/identity­-mgt.properties file.

Authentication.Policy.Enable=true
Authentication.Policy.Account.Lock.On.Creation=true

For more information, you can read this.

3) If you want to see if an account is locked or not in user profile, you can set "http://wso2.org/claims/identity/accountLocked" claim "Supported By Default", by ticking it in Claim management UI > http://wso2.org/claims > Account Locked > Edit like this.

Then you'll see it in your profile like this.

For a Secondary Userstore


Now, let's try the same with a Secondary userstore. Say you have already added a Secondary Userstore with domain "WSO2". Now we need to map a user attribute from that userstore  to http://wso2.org/claims/identity/accountLocked  claim. 

Let's say we map above claim to an attribute named "locked" in your secondary userstore. You can map it like this. 

After doing that, user accounts in secondary userstore will also be locked once they are created.

That's all. Feel free to ask related questions below.

Sunday, March 13, 2016

[WSO2 APIM] Setting up API Manager Distributed Setup with Puppet Scripts





In this post we are going to use puppet to setup a 4 node API Manager distributed setup. You can find the puppet scripts I used, in this git repo.

NOTE: This blog post can be useful to troubleshoot any issues you get while working with puppet.

In my puppet scripts there are below IPs of the nodes I used. You have to replace them with yours.

Puppet Master/MySQL :   192.168.57.92
Publisher:   192.168.57.93
Store:   192.168.57.94
Key Manager:   192.168.57.96
Gateway:   192.168.57.97

That's just some information. Now let's start setting up each node, one by one.

1) Configure Puppet Master/ MySQL Node 

1. Install NTP, Puppet Master and MySQL.

> sudo su
> ntpdate pool.ntp.org ; apt-get update && sudo apt-get -y install ntp ; service ntp restart
> cd /tmp
> wget https://apt.puppetlabs.com/puppetlabs-release-trusty.deb
> dpkg -i puppetlabs-release-trusty.deb
> apt-get update
> apt-get install puppetmaster
> apt-get install mysql-server


2. Change hostname in /etc/hostname to puppet (This might need a reboot)

3. Update /etc/hosts with below entry. 

127.0.0.1 puppet


4. Download and copy https://github.com/bhathiya/apim-puppet-scripts/tree/master/puppet directory to /etc/puppet

5. Replace IPs in copied puppet scripts. 

6. Before restarting the puppet master, clean all certificates, including puppet master’s certificate which is having its old DNS alt names.

> puppet cert clean --all


7. Restart puppet master

> service puppetmaster restart

8. Download and copy jdk-7u79-linux-x64.tar.gz to /etc/puppet/environments/production/modules/wso2base/files/jdk-7u79-linux-x64.tar.gz

9. Download and copy wso2am-2.0.0-SNAPSHOT.zip to 
/etc/puppet/environments/production/modules/wso2am/files/wso2am-2.0.0-SNAPSHOT.zip

10. Download and copy https://github.com/bhathiya/apim-puppet-scripts/tree/master/db_scripts directory to /opt/db_scripts

11. Unzip wso2am-2.0.0-SNAPSHOT.zip and copy wso2am-2.0.0-SNAPSHOT/dbscripts directory to /opt/db_scripts/dbscripts

12. Download and copy https://github.com/bhathiya/apim-puppet-scripts/tree/master/run_puppet.sh file to /opt/run_puppet.sh (Copy required private keys as well, to ssh to puppet agent nodes)

13. Open and update run_puppet.sh script as required, and set read/execution rights.

> chmod 755 
run_puppet.sh