Showing posts with label Human workflow. Show all posts
Showing posts with label Human workflow. Show all posts

Monday, February 4, 2013

Custom SQL authenticator configurations on weblogic -Part1



I had a scenario where we were not able to authenticate users against LDAP and access to LDAP was not provided. So the next option was to get export of the user data and have a custom SQL authentication configured on the weblogic server.
So we had a person table with all user tables. But there were couple of issues when we tried to configure custom sql authentication. In our scenario the user gets automatically authenticated in the J2ee application, so the authentication to Human worklist application was not required, so we had the option of hardcoding a single password so that its easy for j2ee web app to call worklist api to access tasks based the user id alone.
The steps for configuring the custom sql authenticator can be found in reference blogs listed below.


Issue#1
Since the PERSON table didn’t have password column, I tried assigning the query select welcome1 from dual query to retrieve the password. So for all users it will return welcome1 as password. But it didnt work.
<wls:sql-get-users-password>SELECT select ‘welcome1’ from dual </wls:sql-get-users-password>

Error stackTrace
------------------------------
<Jan 15, 2013 9:19:53 AM IST> <Notice> <WebLogicServer> <BEA-000360> <Server started in RUNNING mode>
<Jan 15, 2013 9:22:39 AM IST> <Error> <Security> <BEA-000000> <[Security:090759]A SQLException occurred while retrieving password informatio
n
java.sql.SQLException: Invalid column index
        at oracle.jdbc.driver.OraclePreparedStatement.setStringInternal(OraclePreparedStatement.java:6336)
        at oracle.jdbc.driver.OraclePreparedStatement.setString(OraclePreparedStatement.java:6306)
        at oracle.jdbc.driver.OraclePreparedStatementWrapper.setString(OraclePreparedStatementWrapper.java:303)
        at weblogic.jdbc.wrapper.PreparedStatement.setString(PreparedStatement.java:908)
        at weblogic.security.providers.authentication.shared.DBMSSQLRuntimeQueryImpl.passwordStringQuery(DBMSSQLRuntimeQueryImpl.java:88)
        Truncated. see log file for complete stacktrace

Issue #2
I tried using PERSON and SOA_PASSWORD tables with emailaddress and Password column respectively .Email address from PERSON and password from SOA_PASSWORD table.
This also throws error

Error Stacktrace
--------------------------
java.sql.SQLException: Invalid column index
        at oracle.jdbc.driver.OraclePreparedStatement.setStringInternal(OraclePreparedStatement.java:6336)
        at oracle.jdbc.driver.OraclePreparedStatement.setString(OraclePreparedStatement.java:6306)
        at oracle.jdbc.driver.OraclePreparedStatementWrapper.setString(OraclePreparedStatementWrapper.java:303)
        at weblogic.jdbc.wrapper.PreparedStatement.setString(PreparedStatement.java:908)
        at weblogic.security.providers.authentication.shared.DBMSSQLRuntimeQueryImpl.passwordStringQuery(DBMSSQLRuntimeQueryImpl.java:88)
        Truncated. see log file for complete stacktrace

This works properly.
Conclusion :-- User and Password queries have to be on same table.

Solution
----------
finally created a VIEW -- SOA_PASSWORD_VIEW with à  SELECT person.EMAILADDRESS, 'welcome1' FROM PERSON person;

CREATE OR REPLACE FORCE VIEW "SOA_PASSWORD_VIEW" ("EMAILADDRESS", "PASSWORD") AS   SELECT person.EMAILADDRESS, 'welcome1' FROM PERSON person;

Sample queries you add in config.xml

Code snippet from config.xml
--------------------------------------------------------------

<wls:sql-get-users-password>SELECT PASSWORD FROM SOA_PASSWORD_VIEW WHERE EMAILADDRESS = ?</wls:sql-get-users-password>
        <wls:sql-user-exists>SELECT EMAILADDRESS FROM SOA_PASSWORD_VIEW WHERE EMAILADDRESS = ?</wls:sql-user-exists>
        <wls:sql-list-member-groups>SELECT ROLES_NAME FROM PERSON_ROLE WHERE PERSON_EMAILADDRESS = ?</wls:sql-list-member-groups>
        <wls:sql-list-users>SELECT EMAILADDRESS FROM SOA_PASSWORD_VIEW WHERE EMAILADDRESS LIKE ? and rownum &lt; 10</wls:sql-list-users>
        <wls:sql-list-groups>SELECT NAME FROM ROLE WHERE NAME LIKE ? and rownum &lt; 10</wls:sql-list-groups>
        <wls:sql-group-exists>SELECT NAME FROM ROLE WHERE NAME = ?</wls:sql-group-exists>
        <wls:sql-is-member>SELECT PERSON_EMAILADDRESS FROM PERSON_ROLE WHERE ROLES_NAME = ? AND PERSON_EMAILADDRESS = ?</wls:sql-is-member>
        <wls:password-style>PLAINTEXT</wls:password-style>
        <wls:sql-create-user>INSERT INTO SOA_PASSWORD_VIEW (EMAILADDRESS,PASSWORD) VALUES ( ? , ? )</wls:sql-create-user>
        <wls:sql-remove-user>DELETE FROM SOA_PASSWORD_VIEW WHERE EMAILADDRESS = ?</wls:sql-remove-user>
        <wls:sql-remove-group-memberships>DELETE FROM PERSON_ROLE WHERE PERSON_EMAILADDRESS = ? OR ROLES_NAME = ?</wls:sql-remove-group-memberships>
        <wls:sql-set-user-password>UPDATE SOA_PASSWORD_VIEW SET PASSWORD = ?</wls:sql-set-user-password>
        <wls:sql-create-group>INSERT INTO ROLE(NAME) VALUES ( ? )</wls:sql-create-group>
        <wls:sql-add-member-to-group>INSERT INTO PERSON_ROLE (ROLES_NAME,PERSON_EMAILADDRESS) VALUES( ?, ?)</wls:sql-add-member-to-group>
        <wls:sql-remove-member-from-group>DELETE FROM PERSON_ROLE WHERE ROLES_NAME = ? AND PERSON_EMAILADDRESS = ?</wls:sql-remove-member-from-group>
        <wls:sql-remove-group>DELETE FROM ROLE WHERE NAME = ?</wls:sql-remove-group>
        <wls:sql-remove-group-member>DELETE FROM PERSON_ROLE WHERE ROLES_NAME = ?</wls:sql-remove-group-member>
        <wls:sql-list-group-members>SELECT PERSON_EMAILADDRESS FROM PERSON_ROLE WHERE ROLES_NAME = ? AND PERSON_EMAILADDRESS LIKE ? and rownum &lt; 10</wls:sql-list-group-members>
      </sec:authentication-provider>

This basically covers the initial DB setup and issues faced while configuring the Custom SQL authenticator. Thanks to Bhupinder,Ram and Venkat for helping with this configuration

Resources:

Wednesday, January 30, 2013

Passing custom attributes through Human workflow TaskQuery webservice

In my project there were multiple modules like task Management and Project Module. Each module has human workflow implemented .Customer requirement is to list all the tasks from different modules under a single Manage Tasks page.  So we had to differentiate the different human tasks from each module while listing and fetching details specific to the tasks.  So we had to pass some unique values as part of the payload while the j2ee application queries the TaskService API.
The way to do is to use the flex fields under systemMessageAttributes .
In the assign operation of Human task invocation assign the attributes that need to be passed. Since we pass in the category or module as textAttribute2 the web app will use that to identify which module the id belongs to and fetched details based on the id from corresponding module tables.
Refer table below.


Output values
Human TASKQueryAPI
ID
$initiateTaskInput.payload/task:task/task:systemMessageAttributes/task:textAttribute1
CATEGORY
$initiateTaskInput.payload/task:task/task:systemMessageAttributes/task:textAttribute2
ACTION
$initiateTaskInput.payload/task:task/task:systemMessageAttributes/task:textAttribute3
EXPIRYTIME
$initiateTaskInput.payload/task:task/task:systemMessageAttributes/task:textAttribute4


For Querying the task list and fetching flex fields

Refer sample payload  in table below.
Method:  queryTasks


Input
   <soapenv:Header/>
   <soapenv:Body>
      <tas:taskListRequest>
         <com:workflowContext>
<com:credential>
               <com:login>georgethomas@geo.com</com:login>
               <com:password>welcome1</com:password>
               <com:identityContext>myrealm</com:identityContext>
            </com:credential>
           </com:workflowContext>
         <tas1:taskPredicateQuery startRow="0" endRow="0">
            <tas1:displayColumnList>
                   <tas1:displayColumn>title</tas1:displayColumn>
                   <tas1:displayColumn>state</tas1:displayColumn>
                  <tas1:displayColumn>createdDate</tas1:displayColumn>
                  <tas1:displayColumn>expirationdate</tas1:displayColumn>
                  <tas1:displayColumn>priority</tas1:displayColumn>
                  <tas1:displayColumn>taskNumber</tas1:displayColumn>
                  <tas1:displayColumn>instanceid</tas1:displayColumn>
                   <tas1:displayColumn>textAttribute1</tas1:displayColumn>
                <tas1:displayColumn>textAttribute2</tas1:displayColumn>
                <tas1:displayColumn>textAttribute3</tas1:displayColumn>
                <tas1:displayColumn>textAttribute4</tas1:displayColumn>

              </tas1:displayColumnList>
          <tas1:predicate>             
            <tas1:assignmentFilter>My</tas1:assignmentFilter> 
              <tas1:clause joinOperator="AND" xmlns="http://xmlns.oracle.com/bpel/workflow/taskQuery">
                <tas1:column>state</tas1:column>
                <tas1:operator>eq</tas1:operator>
                <tas1:value>ASSIGNED</tas1:value>
                      </tas1:clause>
          </tas1:predicate>
         </tas1:taskPredicateQuery>
      </tas:taskListRequest>
   </soapenv:Body>
</soapenv:Envelope>




Output
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
   <env:Header/>
   <env:Body>
      <taskListResponse xmlns="http://xmlns.oracle.com/bpel/workflow/taskQueryService">
         <task xmlns="http://xmlns.oracle.com/bpel/workflow/task">
            <title>Approve Project Tasks :Project Name - SOA Suite Full Migration TaskName data</title>
            <priority>3</priority>
            <processInfo/>
            <systemAttributes>
               <assignedDate>2013-01-29T03:54:59-05:00</assignedDate>
               <assigneeUsers>
                  <id>georgethomas@geo.com</id>
                  <type>user</type>
               </assigneeUsers>
               <createdDate>2013-01-29T03:54:59-05:00</createdDate>
               <digitalSignatureRequired>false</digitalSignatureRequired>
               <expirationDate>2013-01-29T03:59:59-05:00</expirationDate>
               <fromUser>
                  <type>user</type>
               </fromUser>
               <numberOfTimesModified>1</numberOfTimesModified>
               <state>ASSIGNED</state>
               <systemActions>
                  <action>VIEW_TASK</action>
                  <displayName>VIEW_TASK</displayName>
               </systemActions>
               <taskId>eb792a23-7b1a-4c95-bda6-897fe8e88c5f</taskId>
               <taskNumber>200070</taskNumber>
               <updatedBy>
                  <id>workflowsystem</id>
                  <type>user</type>
               </updatedBy>
               <updatedDate>2013-01-29T03:54:59-05:00</updatedDate>
               <version>1</version>
               <taskDefinitionId>dev/TaskExecutionApprovalProcess!1.0/PMTaskApproval</taskDefinitionId>
               <workflowPattern>Participant</workflowPattern>
               <participantName>Project Manager Approval</participantName>
               <assignees>
                  <id>georgethomas@geo.com</id>
                  <type>user</type>
               </assignees>
               <isPartialTask>true</isPartialTask>
            </systemAttributes>
         <systemMessageAttributes>
               <textAttribute1> 1234</textAttribute1>
               <textAttribute2>TASK</textAttribute2>
               <textAttribute3>APPROVE,REJECT </textAttribute3>
               <textAttribute4> </textAttribute4>
            </systemMessageAttributes>

            <callback/>
            <sca/>
            <taskDefinitionId>dev/TaskExecutionApprovalProcess!1.0/PMTaskApproval</taskDefinitionId>
            <mdsLabel>soa_c0dc1fb9-f1b7-4e5c-80d2-6520f9eb96d8</mdsLabel>
            <customAttributes/>
         </task>
     
</taskListResponse>
   </env:Body>
</env:Envelope>