The WebView used in a Cordova application does not prompt the user for credentials or for a client certificate as a regular browser does when this information is not provided. In addition, on iOS the WebView does not provide any feedback when incorrect credentials are used.
The AuthProxy plugin can be used to handle the communication for an app and will present a dialog for the user to enter credentials or to choose a client certificate when it is handling the communications. An alternate option is to use the Android Crosswalk plugin which can also handle basic authentication challenges.
When an app needs to provide a certificate to the server to identify itself this is known as client authentication or mutual authentication. An example of this is if you are required to provide a client certificate as part of the onboarding process to register with an application or perhaps to access an OData provider (not needed to complete the example). This occurs mostly in Business to Business (B2B) applications. This is different from most business to consumer or B2C websites where it is only the server that authenticates itself to the client with a certificate that has been signed by a certificate authority (CA) such as an online banking site.
For additional details on the AuthProxy plugin see C:\SAP\MobileSDK3\KapselSDK\docs\api\sap.AuthProxy.html or Using the AuthProxy Plugin.
The following two examples demonstrate the functionality of the AuthProxy plugin.
Making an OData request through the AuthProxy Plugin
Using Client Certificates
The following steps will demonstrate what happens when an incorrect password is sent to a backend OData endpoint and how this behavior can be improved with the AuthProxy plugin.
- Modify the sample from the Logon Plugin section.
In index.html, add the following button below the Unlock button.
<button id="chgPwd" onclick="sap.Logon.changePassword(logonSuccessCallback, errorCallback)">Change Password</button>
- Edit C:\Kapsel_Projects\LogonDemo\config.xml and add the following setting. Note that in SP09, this value defaults to true for iOS and false for Android via the platform config.xml and setting the value here will overwrite it.
<preference name="SAPKapselHandleHttpRequests" value="false" />
- Prepare, build and deploy the project.
cordova run android or cordova run ios
Choose Unregister, Register, provide the valid username and password, and then once registered, click on Read. Notice that the data is returned.
On Android, click on the change password button and change it to an invalid value. Exit the app and remove it from memory (BCP 1570685116). Reopen the app and press the read button. On Android the 401 exception is returned.
- The following steps demonstrate how this can be improved when the AuthProxy plugin intercepts the requests.
Edit C:\Kapsel_Projects\LogonDemo\config.xml and instruct the AuthProxy plugin to handle HTTP requests.
<preference name="SAPKapselHandleHttpRequests" value="true" />
- Prepare, build and deploy the project.
cordova run android or cordova run ios
- The OData connection is proxied through the SMP 3.0 server and when the OData endpoint challenges for credentials, the AuthProxy plugin will first send the credentials used in the registration to the SMP 3.0 server. If those fail, then the credential screen is shown.
Note, the user should at this point click on the Change Password button again and change the password to the correct password, otherwise the next time the app is removed from memory and restarted the Enter Credentials popup will appear.
This example will demonstrate how to use the AuthProxy plugin to register with the SMP 3.0 server using a client certificate and how to use a client certificate in a request to access an OData endpoint. Before continuing, complete HTTPS in the Security Appendix as this is required to be setup before adding client authentication.
The Open SSL Toolkit will be used to create a certificate authority that will sign a client certificate.
Note this example is not using the Logon plugin to perform the registration as the Logon plugin requires using SAP Afaria to provide a client certificate or the CertificateProvider interface. See SAP Afaria and Kapsel and X.509 Certificate Interface for additional details on how to use client certificates with the Logon plugin.
This example can be run on an Android device or emulator.
Note that on iOS, only certificates that have been loaded into the applications keychain are available to be selected. See Making Certificates and Keys Available To Your App and Finding a certificate for further details. A solution to this problem is to use an MDM solution such as SAP Mobile Secure or SAP Afaria to provision the application with a certificate using the Certificate Provider Interface of the Logon plugin or to use Keychain Sharing with an app that has a certificate in its shared keychain.
Note, the following instructions are meant for demonstration purposes only. Security in a production environment should be managed by your company’s security professional.
- Modify the serverkey for port 8082 which is configured for client authentication. Change the keyAlias from smp_crt to serverkey. Note, changes to this file require a server restart before they take effect.
C:\SAP\MobilePlatform3\Server\config_master\org.eclipse.gemini.web.tomcat\default-server.xml <Connector smpConnectorName="mutualSSL" protocol="com.sap.mobile.platform.coyote.http11.SapHttp11Protocol" port="8082" maxThreads="200" scheme="https" secure="true" SSLEnabled="true" ciphers="TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA" keyAlias="serverkey" clientAuth="true" sslProtocol="TLS" sslEnabledProtocols="TLSv1.2"/>
- If on windows, download the Open SSL Toolkit from Shining Light Productions. Specifically download the latest Win64 OpenSSL v1.0.X Light and if required Visual C++ 2008 Redistributables (x64).
- Create a batch file to set the path and add an environment variable. In a command window execute the bat file.
PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program Files\Java\jdk1.7.0_45\bin;C:\OpenSSL-Win64\bin; set OPENSSL_CONF=c:\OpenSSL-Win64\bin\openssl.cfg
- A useful tool for examining a server port is to run the following commands.
openssl s_client -connect localhost:8080 > c:\temp\8080.txt openssl s_client -connect localhost:8082 > c:\temp\8082.txt
8080.txt will contain the following text.
no peer certificate available --- No client certificate CA names sent
Which indicates that the server is not using a certificate (ie, no https, no encryption, or identification).
8082.txt is interesting in that it will indicate what the acceptable list of certificate authorities that the server will accept is. This means that it will only accept a client certificate that has been signed by one the listed certificate authorities.
Acceptable client certificate CA names /C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 1999 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 4 Public Primary Certification Authority - G3 /C=US/O=Equifax/OU=Equifax Secure Certificate Authority ... /C=CA/ST=Ontario/L=Waterloo/O=SAP/OU=SAP Canada/CN=demoRootCA
The last entry will appear after following the steps below which are to create a certificate authority named demoRootCA which will be used to sign a client certificate named user1. After following the below instructions, an app will be created that will be able to pass in a client certificate named user1 to the SMP 3.0 server during the registration process and the SMP 3.0 server will accept the registration because it will trust the certificate authority named demoRootCA.
- Edit the file C:\OpenSSL-Win64\bin\openssl.cfg. Under the heading CA_default a set of directories are specified and the names of various files such as the CA certificate, the private_key name of the CA certificate. Set these two to a value such as demoRootCA.
- Under the section req_distinguished_name, add properties where desired so that default values are provided. The following are a few examples
countryName = Country Name (2 letter code) countryName_default = CA stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = Ontario localityName = Locality Name (eg, city) localityName_default = Waterloo 0.organizationName = Organization Name (eg, company) 0.organizationName_default = SAP
- Create the directory structure and required files for Open SSL.
cd C:\OpenSSL-Win64 mkdir certs cd certs mkdir demoCA cd demoCA type NUL > index.txt echo 01 > serial mkdir newcerts mkdir private cd C:\OpenSSL-Win64\certs
- Create a private key for the CA.
openssl genpkey -des3 -out demoRootCA.key -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -pass pass:112233
- Self-sign the CA and move the private key to the private folder.
openssl req -new -x509 -days 3650 -key demoRootCA.key -out demoRootCA.crt move demoRootCA.crt demoCA move demoRootCA.key demoCA\private
- Import CA into SMP 3.0 keystore and restart the server.
keytool -import -deststorepass changeit -destkeystore C:\SAP\MobilePlatform3\Server\configuration\smp_keystore.jks -file demoCA\demoRootCA.crt -alias demoRootCA
The SMP 3.0 server will now accept client certificates that have been signed by this certificate.
- The demoRootCA can be viewed using the following command.
keytool -list -v -keystore C:\SAP\MobilePlatform3\Server\configuration\smp_keystore.jks -alias demoRootCA -storepass changeit
- Create a private key for a client cert.
openssl genpkey -des3 -out user1.key -algorithm RSA -pass pass:changeit
- Generate a signing request for the client cert.
openssl req -new -key user1.key -out user1.csr -passin pass:changeit
Note, enter can be pressed for the question A challenge password.
- Use the CA to sign the client cert.
openssl ca -out user1.crt -infiles user1.csr
- Package up the private and public client key in a format that can be imported into a desktop browser or a mobile device. The public and private key of the client certificate must be imported to the mobile device so the PKCS12 format is used.
openssl pkcs12 -export -out user1.p12 -inkey user1.key -in user1.crt -name user1 -certfile demoCA\demoRootCA.crt -passin pass:changeit -passout pass:changeit
- Follow the steps shown in Configuring a Kapsel App in the Management Cockpitto create an Application with the application id of
Set the endpoint to be
Note that the operation will be processed in the context of the client’s certificate (The SSL_CLIENT_CERT header is passed along in the request).
- Import the user1.p12 file into the personal certificate store. In Chrome, choose Settings > Show Advanced Settings > HTTPS/SSL > Manage certificates > Import > Change the file extension filter to *.p12 and browse to user1.p12. Once completed the client certificate should appear as shown below.
Note, Chrome may need to be started with the option –disable-web-security to enable this example to be run from the file system. Ensure that all instances of Chrome are shut down before restarting. At this point the following register5.html can be used to test out client authentication using desktop Chrome. It requires that the datajs library is placed in the same folder as register5.html.
There is a registry setting that instructs which client certificate should be automatically selected by Chrome. If you do not see a dialog to select a certificate after pressing the register button, it may be that there is a registry setting such as the one shown below which indicates that all web sites that request a client certificate should use a certificate signed by SSO_CA.
See also List of Policies for Chrome.
Also note that Chrome will remember which certificate was selected until it is restarted.
- The next step is to perform a registration using a client certificate from within an app running on a mobile device or simulator.
Create a new project which will perform client authentication to the SMP 3.0 server.
cordova create C:\Kapsel_Projects\AuthProxyDemo com.mycompany.authproxy AuthProxyDemo cd C:\Kapsel_Projects\AuthProxyDemo cordova platform add android cordova plugin add cordova-plugin-console cordova plugin add kapsel-plugin-authproxy --searchpath %KAPSEL_HOME%/plugins cordova create ~/Documents/Kapsel_Projects/AuthProxyDemo com.mycompany.authproxy AuthProxyDemo cd ~/Documents/Kapsel_Projects/AuthProxyDemo cordova platform add ios cordova plugin add cordova-plugin-console cordova plugin add kapsel-plugin-authproxy --searchpath $KAPSEL_HOME/plugins
- In SP09, edit the following file and comment out lines 371 to 385 due to BCP issue https://support.wdf.sap.corp/sap/support/message/1570685289which prevents initializing a CertificateFromStore object without specifying an alias name.
- Replace www\index.html with the contents of register6.html.
- Prepare, build and deploy the app with the following commands.
cordova run android
- In order to successfully make OData requests using client authentication, the backend OData server would need to be configured which is not covered in this guide.
- Note, that when pressing the Register button, the client certificates that could be used to authenticate are shown.
Also note that as of SP09, the certificate selected by the user will be remembered across application restarts on Android. For iOS see also the newly added in SP09 API named setAutoSelectCertificateConfig which when called can enable the behavior of not prompting for client certificate selection when only one certificate exists.
The below links contain some additional information on SSL, certificates, configuring a Tomcat server to use client authentication and how to add an OData producer to Tomcat.
Tomcat SSL How To
Tomcat Mutual Authentication
Hosting OData4J in Tomcat