Saturday, January 31, 2015

Steps to install shibboleth idp on windows with tomcat


1. download zip file for shibboleth-idp installation from
http://shibboleth.net/downloads/identity-provider, do not use the latest 3.0, which is not yet stable as well as well documented. Use 2.4. and unzip it to a folder

2. check java -version to be sure it is 1.7.0 or above

3. execute install.bat, and enable https connection with 9443. Set the identity of your idp, for example
https://torn00461340a.amer.global.corp.sap/idp/shibboleth

4. download tomcat 7 (port 9080 and 9443 are used), and add the server into eclipse

5. add idp.xml as mentioned in https://wiki.shibboleth.net/confluence/display/SHIB2/IdPApacheTomcatPrepare
Set unpackwar to true to avoid an error in eclipse server start.

6. start tomcat from eclipse , and be sure the below query works
http://localhost:9080/idp/status
http://localhost:9080/idp/profile/Metadata/SAML


7 backup and update relying-party.xml MetadataProvider section as below

     <metadata:MetadataProvider id="ShibbolethMetadata" xsi:type="metadata:ChainingMetadataProvider">
         <metadata:MetadataProvider id="IdPMD" xsi:type="metadata:FilesystemMetadataProvider"
                                   metadataFile="C:\opt\shibboleth-idp/metadata/idp-metadata.xml"
                                   maxRefreshDelay="P1D" />
              <metadata:MetadataProvider id="URLMD" xsi:type="metadata:FilesystemMetadataProvider"
                                   metadataFile="C:\opt\shibboleth-idp/metadata/testshib.xml"
                                    />
    </metadata:MetadataProvider>

8 open IDP_HOME/conf/handler.xml, comment out LoginHandler RemoteUser element, and uncomment LoginHandler UsernamePassword element.

9 Open the file IDP_HOME/conf/login.config and uncomment Example LDAP authentication element. Pay attention to the "file:///" part.
   <!-- Login Handlers
    <ph:LoginHandler xsi:type="ph:RemoteUser">
        <ph:AuthenticationMethod>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</ph:AuthenticationMethod>
    </ph:LoginHandler>
 -->
    <!--  Username/password login handler -->
 
    <ph:LoginHandler xsi:type="ph:UsernamePassword"
                  jaasConfigurationLocation="file:///C:\opt\shibboleth-idp/conf/login.config">
        <ph:AuthenticationMethod>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</ph:AuthenticationMethod>
    </ph:LoginHandler>

10 download Windows AD LDS and install it on Windows 7. Use the below online help to to install it - "Office 365 Single Sign-On with Shibboleth 2 whitepaper"
http://www.microsoft.com/en-ca/download/details.aspx?id=35464


11. update login.config with the below info based on AD LDS installation
      edu.vt.middleware.ldap.jaas.LdapLoginModule required
      ldapUrl="ldap://localhost:389"
      baseDn="CN=torn00461340a,DC=SAP"
 userFilter="cn={0}"
 subtreeSearch="true"
          ssl="false"
 tls="false"
 bindDn="cn=ShibbolethServiceAccount,cn=torn00461340a,dc=SAP"
 bindCredential="password";

12 open attribute.resolver.xml, and update LDAP connector element as below
    <!-- Example LDAP Connector -->
 
    <resolver:DataConnector id="myLDAP" xsi:type="dc:LDAPDirectory"
        ldapURL="ldap://localhost:389"
        baseDN="CN=torn00461340a,DC=SAP"
        principal="cn=ShibbolethServiceAccount,cn=torn00461340a,dc=SAP"
        principalCredential="password">
        <dc:FilterTemplate>
            <![CDATA[
                (uid=$requestContext.principalName)
            ]]>
        </dc:FilterTemplate>
    </resolver:DataConnector>
 

13. update attribute-resolver.xml to include assertion required by SP.
for example, the mail attribute
<resolver:AttributeDefinition id="email" xsi:type="Simple" xmlns="urn:mace:shibboleth:2.0:resolver:ad"
        sourceAttributeID="mail">
  <resolver:Dependency ref="ADLDS" />

  <resolver:AttributeEncoder xsi:type="SAML1String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"
        name="urn:mace:dir:attribute-def:mail" />

  <resolver:AttributeEncoder xsi:type="SAML2String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"
        name="urn:oid:0.9.2342.19200300.100.1.3" friendlyName="mail" />
</resolver:AttributeDefinition>


14.update attribute-filter.xml with below segment to allow idp to  release the attribute of givenName to service provider
   <afp:AttributeFilterPolicy id="releaseAttriToTestSP">
        <afp:PolicyRequirementRule xsi:type="basic:ANY" />

        <afp:AttributeRule attributeID="givenName">
            <afp:PermitValueRule xsi:type="basic:ANY" />
        </afp:AttributeRule>
    </afp:AttributeFilterPolicy>


15. Update relying-party.xml to test with testshib to verify the SP can redirect to your IDP and prompt you to input username and password.

              <metadata:MetadataProvider id="URLMD" xsi:type="metadata:FilesystemMetadataProvider"
                                   metadataFile="C:\opt\shibboleth-idp/metadata/testshib.xml"
                                    />

After inputting user name and password, it shows a screen says "Shibboleth-protected TestShib Content. You can also verify the givenName is sent to SP by IDP by using Firefox saml tracer plugin.

Sunday, January 18, 2015

Receive native side notification by javascript using cordova plugin

Usually, the cordova plugin is used to invoke native api from javascript. However, it can also be used by javascript to listen for native side notification. This feature is already used in several cordova build in plugins, such as device motion plugin at https://github.com/apache/cordova-plugin-device-motion.

The basic idea is when calling the cordova plugin's callback method, it also an option to keep the callback alive, so after the cordova plugin API is initially called from javascritp to native side, the native code can keep the callback method in its data member. Whenever the native code needs to send a notification to javascript, it can just call this saved callback method with the notification data, also specify the callback method should be kept alive on javascirpt side in order to get following notification, otherwise, the javascript will delete the callback after it receives the first callback method from native side.

A sample callback made from Android native code are as below

   PluginResult result = new PluginResult(PluginResult.Status.OK, "This is notification data");
   result.setKeepCallback(true);

   _callbackContext.sendPluginResult(result);

Serve static web content by tomcat

The following steps can be used to server static web content by tomcat server, the static web content includes html, image, and js, jsp files.

1. create a subfolder under tomcat's webapps folder, for example, mytestfolder
2. copy html file and js file into the folder, for example, index.html
3. visit localhost:8080/mytestfolder/index.hmtl to visit the html file

In addition, jsp files can also be put in the folder and serve the client request without any servlet configuration change.

Sometimes when debugging tomcat, an error of ""Several ports (8080, 8009) required by Tomcaat v8.0 Server at localhost are already in use", to solve the issue, going to tomcat bin folder and run the below commend to close the running tomcat instance.


bash shutdown.sh

Friday, January 2, 2015

Enable browser cross domain request on Chrome and IE

When testing javascript, sometimes it is helpful to enable cross domain request on browser. This can be done on Chrome and IE

Chrome
1. When starting chrome from command line, add the parameter of "--disable-web-security".
Note you may find it does not work. That is because there are some chrome process already running. Some processes will keep running even if you close all chrome browser. Be sure to kill all chrome process from windows task manager, and then start Chrome with this parameter.
Once it is enabled, the browser will show a warning message saying the security is suffered.

IE
Open tools/Internet Option menu, select security tab, click on Custom level button. From settings, enable "Access data source across domains"


Friday, December 19, 2014

How to debug cordova onDeviceReady event

After loading the html page, the cordova will immediately call onDeviceReady event handle, so it is hard to set break pointer to debug the logic in onDeviceReady event.
One option is use javascript setInterval method, so it will hold the javascript until you change the bWait flag from javascript console window

The sample code looks like


  var onDeviceReady = function() {
        var originThis = this;
        var bWait = true;
        var bDone =false;
        var i = 0
        var timer = setInterval(
                function(){
                    if (bWait && i < 10 ){
                        i++;
                        console.log("set bWait to false from console window to continue");
                    }
                    else{
                        if (!bDone){
                            bDone = true;
                            clearInterval(timer);
                            yourOriginalOnDeviceReady.apply(originThis, arguments);
                        }
                    }
                }, 3000);
    }

Actually, this can also be used in other cases for attaching javascript debugger, particularly for the js script loaded into the DOM at runtime by xhr request. Just wrap the original function with the above function should do it.

Wednesday, December 10, 2014

Find ios simulator folder on mac

Option 1
1. While running the app on simulator from xcode, enter a breakpoint or just clicking the pause buttonn
2. in Xcode console window, type the below command
po NSHomeDirectory()
3. copy the path, and then from Finder, click Go->Go To Folder menu, and paste the path, it will show the simulator app bundle folder


Option 2
1. launch ios simulator, click Hardware->device->Manage Device... menu

2. in the opened xcode device screen, find the simulator item, select it, and get the identifier number

3. open Finder on mac and goto the folder of
/Users/<Your UserName>/Library/Developer/CoreSimulator/Devices

4. find the subfolder that has the same name.

5 go to data\applications folder and check the application name in each subfolder to find the you want to check

Thursday, November 20, 2014

Variables can be accessed by a javascript function

When a javascript function is called, sometime it is confusing on which variables it can access.
1. parameters passed by caller (decided at runtime)

2. local variables defined within the function,

3. closure variables
    closure variable only depends on where the function is defined, and it also includes different levels of parent scopes all the way up to the global scope.

4. global variables
   global variable is accessible in the sense of a special kind of closure variable, as all function will end up in the global scope.

5. this properties
   The properties of this object can be accessed by using this.property within a function. However, when the function is called, this object may be changed from time to time depending on how it is called. So be sure to check the property is valid before using it.