Pages

Sunday, 10 August 2014

Accessing REST Service secured with Basic Authentication in ADF Mobile

Usecase:
This usecase talks about how a REST service secured with basic authentication can be accessed in ADF Mobile. For this demo, I have used a REST service which returns employee information, and the service itself has been secured with basic authentication.

Pre-requisites:
JDeveloper 11.1.2.4.0

Steps:
At the service end
Create a REST Service and secure it with basic authentication. Deploy the service to integrated weblogic server and note down the target URL.
Configure ADF Security:
To configure security in ADF Mobile, first create an ADF app and secure it with basic authentication.
1)   Create a new ADF Fusion application.
2)   Create a jspx page in the ViewController project. Go to the menu item: Application -> Secure -> Configure ADF Security. Select ADF Authentication. Keep the defaults and select ‘Redirect upon successful authentication’ and click ‘Generate default’. Finish the wizard. Deploy the app or run the page in the integrated server and note down the URL.These are the same steps as my previous post.

Mobile app configuration:
1)   Create a new ADF Mobile application.
2)   In the ApplicationController, invoke the Web Service Data control wizard. Create the connection by specifying authentication type as Basic and supplying the username/password/realm details. Supply the resource URL and after the method configurations, finish the wizard to create the DC.

3)   Next, go to adfmf-application.xml under Application Resources -> Descriptors -> ADF META-INF. Go to the Security tab and add a new Application Login Server. In the dialog for 'Edit ADF Mobile Login Connection', provide the Login URL and Logout URL as the URL generated in step 2. Remember to use IP address instead of localhost. Also, add a cookie 'JSESSIONID'. Test Connection to ensure the connection is fine. Also, check the checkbox 'Include login server cookie in REST calls'. This will ensure that the JSESSIONID cookie value flows through to the REST service. Close the wizard.
    

4)   To ensure that the basic auth credentials entered in the login page flow through to the REST service call, there is one last step required.
      Go to connections.xml file present under Application Resources -> Descriptors -> ADF META-INF. Look for the adfCredentialStoreKey attribute set for the login window. Set the adfCredentialStoreKey attribute for the service's reference tag with the same value, either manually or through the PI, as shown. 
     


5)   Design the amx pages by D&D an operation of the secure service from DC palette to the page. Deploy the app. The user must be prompted for login credentials on feature load. After the credentials are entered, user should be able to view responses from the secure service without the need to enter credentials again.
      Some snapshots from my app are shown below. Both features are secure in my case, with 'Welcome' being the default one. On app load, user is prompted for credentials. Entering valid  credentials takes the user to the Welcome page. If he then tries to access BasicAuthREST feature,  he is not prompted for credentials again, although the data in this page comes from a secure REST  service.
     


Monday, 4 August 2014

Configuring authentication using remote server in ADF Mobile

Usecase:
This usecase shows how basic authentication can be configured using a remote login server in ADF Mobile.

Pre-requisites:
JDeveloper 11.1.2.4.0.
For Jdeveloper 12.1.3.0.0, check Updates section below.

Steps:
1) Create a new ADF Fusion application.
2) Create a jspx page in the ViewController project. Go to the menu item: Application -> Secure -> Configure ADF Security. Select ADF Authentication. Select HTTP Basic Authentication. Keep the defaults and select 'Redirect upon successful authentication' and click 'Generate Default'. Finish the wizard. Deploy the app or run the page in the integrated server and note down the URL.
3) Create a new ADF Mobile application. Create two new features in it. Let us secure one feature, feature1 and leave the other feature, feature2 unsecure. Create AMX pages for this feature with some basic text content such as hello.
In adfmf-feature.xml, select feature1. Go to Security tab. Select 'Enable Feature Security'. Select Credential Authentication as 'remote'.



4) Go to adfmf-application.xml under Application Resources -> Descriptors -> ADF META-INF. Go to the Security tab and add a new Application Login Server. In the dialog for 'Edit ADF Mobile Login Connection', provide the Login URL and Logout URL as the URL generated in step 2. Remember to use IP address instead of localhost. Also, add a cookie 'JSESSIONID'. Test Connection to ensure the connection is fine. Close the wizard.

5) Deploy the app to an emulator/device.
A login screen as shown below will be seen. On entering the user credentials, the feature gets rendered.

References:
http://docs.oracle.com/cd/E35521_01/doc.111230/e24475/security.htm#CDDGDFGJ

Updates:
For 12.1.3.0.0 with MAF, the configuration is a bit different. Follow steps 1 and 2 as mentioned for 11.1.2.4 above. To enable security for a feature in MAF, do the following:



Go to maf-application.xml under Application Resources -> Descriptors -> ADF META-INF. Go to the Security tab and add a new Application Login Server. In the dialog for 'Create MAF Login Connection', select Connection mode as 'Remote' and provide connection name. Uncheck the two checkboxes. In HTTP Basic tab, provide URL of the secured ADF app(use IP address).

                 

Deploy the app.

Friday, 1 August 2014

Passing Custom SOAP Headers in ADF Mobile

Usecase:
This document shows how custom SOAP Headers can be passed in ADF Mobile to make web service calls. 

Pre-requisites:
JDeveloper Version - 11.1.2.4.0 with Mobile support
For the purpose of this demo, I am using a basic Hello service secured with the OWSM policy ‘oracle/wss_username_token_service_policy’. Additionally, the service responds to only those clients who send a custom SOAP Header with value ‘ClientABC’. Any other value in the header will receive “Invalid Client---Access denied.” as response. You may create the service on similar lines or use the attached service from here (Note that this service has been created in 12.1.2.0.0 build)

Steps:
  1. Create a new ADF Mobile application.
  2. In the ApplicationController project, create a data control for the WSDL URL of the above service.
  3. Since we need to pass some additional header information in the SOAP Envelope, we need to implement the method public SoapHeader[] getAdditionalSoapHeaders() in our own way.
To do this, in the ApplicationController project, create a new Java Class. Call it ‘CustomHeaderClass.java’. Let the class extend SOAPProvider from the package oracle.adfinternal.model.adapter.webservice.provider.soap.SOAPProvider.




Implement the getAdditionalSoapHeaders() method as shown:

    public SoapHeader[] getAdditionalSoapHeaders() {
        System.out.println("In getAdditionalSoapHeaders");
        SoapHeader header[] = new SoapHeader[2];
        SoapHeader token = null;
        SoapHeader user = null;
        SoapHeader pass = null;
    
        header[0] = new SoapHeader(
                    "www-testNamespace.com","ClientName","ClientABC"); //specify the namespace, tag name and the client value
        header[1] = new SoapHeader(
                    "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd","Security");
        token = new SoapHeader(
                   "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd","UsernameToken");
        user = new SoapHeader(
                   "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd","Username","weblogic");
        pass = new SoapHeader(
                   "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd","Password","weblogic1");
        header[1].addChild(token);
        token.addChild(user);
        token.addChild(pass); 
        return header;
}
In my case, a valid request structure was as below. Thus, the above code was based on this structure.


<?xml version = '1.0' encoding = 'UTF-8'?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:ns2="http://project1/"> 
<env:Header>
<ClientName xmlns="www-testNamespace.com">ClientABC</ClientName>
 <ns1:Security>
<ns1:UsernameToken>
<ns1:Username>weblogic</ns1:Username>
<ns1:Password>weblogic1</ns1:Password>
  </ns1:UsernameToken>
 </ns1:Security>
</env:Header>
<env:Body>
 <ns2:helloWorld/>
 </env:Body>
</env:Envelope>


  1. Also, open the DataControls.dcx file and search for provider="oracle.adfinternal.model.adapter.webservice.provider.soap.SOAPProvider". Change this default provider to point to the Provider class we just implemented. In this case, change the line to provider=" application.CustomHeaderClass”.

   5. D&D the method in the DC to an AMX page along with an output text box. If you invoke the method and check the request in the analyzer, you should be able to see the headers being passed.



References: