Wednesday, May 1, 2013

How to configure API visibility level when multiple user stores are configured - WSO2 API Manager


WSO2 API Manger provides set of functionalities for API Publishers. API Visibility control functionality is one of them, where API visibility can be either 'Public' or 'Restricted'. If it is set to 'Public' then the API is visible through the API Store to all API subscribers and also anonymous users of the API store.  And, If it set to 'Restricted', then only the specified users who having the required role permission can see the API through the API Store.

We don't need to do any configuration changes to use this feature in normal scenarios (i.e standalone API Manager distribution). But, there is a some special case where we need to do some additional configurations to work this functionality; In a distributed setup where API publisher and API Store are separated and they have pointed to use different user-stores, then we need to do some configuration changes to work this  functionality.

In a production deployment of API Manager, depending on company security policies, you can either use same user-store for both API publisher and API store, or use two separate user-stores for them. Usually in most of production setups they tends to use internal user-store for API publisher and some external user-store for API Store. Even though, we use separate user-stores for API Publisher and API Store, we need to point them to a same permission store to work API visibility functionality. (Otherwise, even you have made the API visibility as public ,this API will not available in API Store, without login to it).  Following guide will explain how we can configure API Publisher and API Store nodes to use same permission store while they are pointed to use different user-stores.

User Manager has two types of storages. One is user store and the other is permission store. All resource permissions are stored in the permissions store while users are stored in user store. Usually when we pointed to two different user-stores, it will use separate permission stores as well, unless we have explicitly configured it to use same permission store. Because of that, when publisher grant permission on api registry resource, it will reflect only on the publisher permission store. Those permission will not available on the permission store of API Store.

So we need to share the same permission store used in Publisher with API Store as well. (Permission store contains only Role-Permission mapping. Sharing permission store will not share the the user details).

The global data-source defined in user-mgt.xml (if you open the user-mgt.xml, it can be found inside the top most <Configuration> section.) is used for permission store. When you don't have defined the <Property name="dataSource"> in JDBCUserStoreManager, the same data-source defined above for permission store will use for user store as well. But, you can defined some other data-source inside <UserStoreManager> for user store while using , something else for permission store.

You may need to do the following configuration changes to use same permission store of publisher within the API Store,

1. In 'master-datasources.xml' of API Store, add new data-source entry to use user-manager data-source of publisher.
eg: If the user-manager data source defined in Publisher is as follows, then add this data-source to 'master-datasources.xml' of API Store as well.

<datasource>
            <name>pubdb</name>
            <description>The datasource used for registry and user manager</description>
            <jndiConfig>
                <name>jdbc/pubdb</name>
            </jndiConfig>
            <definition type="RDBMS">
                <configuration>
                    <url>jdbc:mysql://localhost:3306/pubdb?autoReconnect=true&amp;relaxAutoCommit=true&lt;/url>
                    <username>root</username>
                    <password>root</password>
                    <driverClassName>com.mysql.jdbc.Driver</driverClassName>
                    <maxActive>50</maxActive>
                    <maxWait>60000</maxWait>
                    <testOnBorrow>true</testOnBorrow>
                    <validationQuery>SELECT 1</validationQuery>
                    <validationInterval>30000</validationInterval>
                </configuration>
            </definition>
        </datasource>

2. In user-mgt.xml of API Store, change the data-source property(i.e <Property name="dataSource">) defined in '<Configuration>' section to use the above data source. (The data-source defined in this <Configuration> section, is used for permission store. By changing configuration as above we, point permission store of API store to permission store of publisher).

 eg:
<Configuration>
                <AdminRole>admin</AdminRole>
                <AdminUser>
                     <UserName>admin</UserName>
                     <Password>admin</Password>
                </AdminUser>
            <EveryOneRoleName>everyone</EveryOneRoleName> <!-- By default users in this role sees the registry root -->
<!-- <Property name="dataSource">jdbc/storedb</Property> -->
<Property name="dataSource">jdbc/pubdb</Property>
            <Property name="MultiTenantRealmConfigBuilder">org.wso2.carbon.user.core.config.multitenancy.SimpleRealmConfigBuilder</Property>
        </Configuration>

3. Add the, user-store data source of API Store inside the JDBCUserStoreManager configuration. (i.e <Property name="dataSource">jdbc/storedb</Property>)
eg:
<UserStoreManager class="org.wso2.carbon.user.core.jdbc.JDBCUserStoreManager">
<Property name="dataSource">jdbc/storedb</Property>
<Property name="ReadOnly">false</Property>
            <Property name="MaxUserNameListLength">100</Property>
            <Property name="IsEmailUserName">false</Property>
            <Property name="DomainCalculation">default</Property>
            <Property name="PasswordDigest">SHA-256</Property>
            <Property name="StoreSaltedPassword">true</Property>
            <Property name="UserNameUniqueAcrossTenants">false</Property>
            <Property name="PasswordJavaRegEx">^[\S]{5,30}$</Property>
            <Property name="PasswordJavaScriptRegEx">^[\\S]{5,30}$</Property>
<Property name="UsernameJavaRegEx">^[^~!#$;%^*+={}\\|\\\\&lt;&gt;,\'\"]{3,30}$</Property>
<Property name="UsernameJavaScriptRegEx">^[\\S]{3,30}$</Property>
<Property name="RolenameJavaRegEx">^[^~!#$;%^*+={}\\|\\\\&lt;&gt;,\'\"]{3,30}$</Property>
<Property name="RolenameJavaScriptRegEx">^[\\S]{3,30}$</Property>
            <Property name="UserRolesCacheEnabled">true</Property>
<Property name="maxFailedLoginAttempt">0</Property>
        </UserStoreManager>

By doing above configuration changes, we will use same permission store for API Store and Publisher and you should be able to see the APIs that create with public visibility, without login to API Store.

No comments:

Post a Comment