Monday, December 23, 2013

Accessing Credential Store from ADF application

Sometimes we need to use credentials (username and password) in ADF applications to connect to backend applications.

We had a scenario where we needed to add attachments to the Imaging server using imaging webservice from an adf form. To access this particular service, we needed to use credentials of the Admin user, in our case it was 'weblogic'.

Considering these credentials can be different per environment, you would be tempted to put it in a properties file or in a database table. This is a big security risk considering the passwords can be in plain text format. You can apply encryption and decryption mechanism to store the password in encrypted format, but that requires additional development time and still not fool proof.

Oracle Platform Security Services includes the Credential Store Framework (CSF), a set of APIs that applications can use to create, read, update, and manage credentials securely OPSS is inherent part of Fusion Middleware Security and can be used within applications running on fusion middleware platform.
The Credential store basically comprises of maps with unique names and each map can store or retrieve credentials based on a unique Key, for which we need to create a credential store entry for the Key, update the jazn-data.xml file of your ADF application to allow credential store to be accessed by the application and finally write a java code to access the credential store.

Below are the steps you need to follow to access the credential store from ADF application:
  1. Adding a key "basic.credential" to an already existing map "oracle.wsm.security"
  2. Log  into Enterprise Manager and select your weblogic domain , from the drop down select securities and then click on Credentials


  3. Select the map(in our case we are using an already existing  map “oracle.wsm.security”) where you want to add the key and click on Create Key


  4. Following window opens , where you can fill the details and click OK


  5. Your key is now created and map is updated


  6. Open you adf project and update its jazn-data.xml to add following credential access permission to use newly created key in credential store 

    <jazn-policy>
    <grant>
                <grantee>
                    <codesource>
                        <url>file:${domain.home}/servers/${weblogic.Name}/tmp/_WL_user/CodeFormApp_V2.0/
    </url>
                    </codesource>
                </grantee>
                <permissions>
                    <permission>
                        <class>oracle.security.jps.service.credstore.CredentialAccessPermission</class>
                 <name>context=SYSTEM,mapName=oracle.wsm.security,keyName=basic.credential</name>
                        <actions>*</actions>
                    </permission>
                </permissions>
    </grant>
    </jazn-policy>


    Above mentioned policy enables access to the credential store for the application containing the java class implementing the credential store access.
    Where CodeFormApp_V2.0  is the name of our ADF application.

    The name of your application is the name of your EAR and appended with _V2.0 if ADF Security is enabled. You can also validate the path of your deployed application from the value of url in the codesource element of the jazn policy mentioned above. 

  7. Now add the following code to your java class to retrieve the user credentials

    public  String[] getUserCredentials() {
            String[] password = new String[2];
            try {
                JpsContextFactory factory = JpsContextFactory.getContextFactory();
                JpsContext jpsContext = factory.getContext();
                final CredentialStore store =
                    jpsContext.getServiceInstance(CredentialStore.class);
                Credential cred =
                    AccessController.doPrivileged(new PrivilegedExceptionAction<PasswordCredential>() {
                        public PasswordCredential run() throws JpsException {
                            return (PasswordCredential)store.getCredential("oracle.wsm.security",
                                                                           "basic.credential");
                        }
                    });
                PasswordCredential pwdCred = (PasswordCredential)cred;
                password[0] = pwdCred.getName();
                password[1] = new String(pwdCred.getPassword());
            } catch (PrivilegedActionException exc) {
               system.out.println(
                              "Error getting credentials from default store:" +
                              exc.getMessage() + "\nStackstrace: " + exc.getStackTrace());
                exc.printStackTrace();
            }

            return password;
    }

    Where password[0] is the value of username and password[1] is the value of password.

    Above values can be used to access the webservice.


I hope that this code tip helps you out!

Thanks to Siddhartha Agarwal for today's article.

-ryan

3 comments:

  1. Hi Ryan
    I followed your instructions, but i am getting below error
    access: access denied (oracle.security.jps.service.credstore.CredentialAccessPermission context=SYSTEM,mapName=oracle.wsm.security,keyName=FusionCloudWSSecurityKey read)

    Below is my Jazn-data.xml




    file:${oracle.deployed.app.dir}/ERPCloudIntegrationsOutboundADFApplication${oracle.deployed.app.ext}




    oracle.security.jps.service.credstore.CredentialAccessPermission
    context=SYSTEM,mapName=oracle.wsm.security,keyName=FusionCloudWSSecurityKey
    read




    Can you help please, what am i missing.

    ReplyDelete
  2. I am very fond of your blogging and posting. I like you every post.

    ReplyDelete
  3. I am also getting same error "access denied". Can anyone have answer ?

    ReplyDelete