Sunday, May 25, 2014

Login into a Passive STS Relying Party application with Facebook credentials using WSO2 Identity Server

With WSO2 5.0 now you can login into a Passive STS supported application using your Facebook Credentials. I am going to explain how to do that using a sample Relying Party (RP) application written in Java. 


Step 1 : Configuring Passive STS sample application

  • Extract the zip file and copy the .war file into the webapps folder inside the extracted apache-tomcat folder.
  • Run Tomcat by running the catalina.sh file inside the bin folder using : sh catalina.sh run


Step 2 : Configuring the Facebook App

  • Go to Apps > Create a New App

  • Enter an App Name and select an appropriate category and click on Create App. This will take you to the App Dashboard where you can find the AppID and AppSecret.

  • Go to Settings and click on Add platform 

  • Click on website and configure as shown in the screenshot.



  • Go to Settings > Advanced

Here you need to configure security settings as shown in the screenshot



  • Client OAuth Login should be set to Yes and OAuth redirect URL should be set to https://localhost:9443/commonauth .  Click on Save Changes button to save the changes.
The app is not available to general public yet. To make to app available to every Facebook user, you have to submit the app for review. After a review Facebook make the app available to every Facebook user. More information on review process can be find by clicking on Status and Review.

Because the review process is taking some time, you can specify some Facebook users as Developers or Testers. Only the specified here can use this app to Login with Facebook until the App go public.
  • Click on Roles to go the below page and specify the required Facebook users as Developers or Testers.


Step 3 : Configuring Identity Provider

Now you have to configure WSO2 Identity Server. First you need to download the latest version from
  • Extract the zip file and run wso2server.sh file inside the bin directory. (If you are using windows run wso2server.bat instead).
  • Login to the management console using
                           URL :  https://localhost:9443/carbon/
                           User Name : Admin                                        Password : Admin
  • In the Identity Section in the Main tab, click on Add button under Identity Providers.
  • Give a suitable name as the Identity Provider Name.



  • Go to Federated Authenticators > Facebook Configuration and enter the App ID and App Secret values form Facebook app into Client ID and Client Secret fields respectively.
  • Tick both check boxes to enable Facebook Authenticator and Make it the default. 

Step 4 : Configuring Service Provider

  • Now go back to the WSO2 IS Management console. In the Manage Section in the Main tab, click on Add button under Service Providers.
  • Enter PassiveSTSSampleApp in the Service Provider Name text box and click Register. 
  • Go to Inbound Authentication ConfigurationWS-Federation (Passive) Configuration.

  • Now set the configuration as follows:
              Passive STS Realm: :PassiveSTSSampleApp 

   



  • Go to Local and Outbound Authentication Configuration.
  • Select the Identity Provider you created form the drop down under Federated Authentication. 
  • Select the Federated Authenticator option button and select facebook. Click on Update button to save the changes.


    Step 5 : Configuring claim mappings for Facebook.

    • In the Identity Section in the Main tab, click on List button under Identity Providers.
    • Click on the Edit button to edit the facebook identity provider. 
    • Go to Claim Configuration > Basic Claim Configuration
    • Select Define Custom Claim Dialect option under Select Claim mapping Dialect
    • Click on Add Claim Mapping to add custom claim mappings as follows. 

    • You can retrieve all the public information of the user and the email address. Here are some common attribute names. 

      • id
      • email
      • name
      • first_name
      • last_name
      • link
      • gender
      • locale
      • age_range
              
    • More information is available from the following link.
                    https://developers.facebook.com/docs/facebook-login/permissions/v2.0


    • You can map these attributes to any Local Claim URI which you feels suitable. 


      Step 6 : Configuring requested claims for PassiveSTSSampleApp


      • In the Identity Section in the Main tab, click on List button undeNOwr Service Providers.

      • Click on the Edit button to edit the PassiveSTSSampleApp service provider. 

      • Go to Claim Configuration 

      • Click on Add Claim URI  under Requested Claims to add the requested claims as follows. Here you should add the claims you mapped in the Identity Provider claim configuration. 



        • Select a suitable claim for the Subject Claim URI(Please not that email address cannot use without allowing using email addresses as user names in carbon.xml. To allow using email address as usernames uncomment <!--EnableEmailUserName>true</EnableEmailUserName--> in carbon.xml file inside wso2is-5.0.0/repository/conf)

        Step 7 : Login to PassiveSTSSampleApp using Facebook credentials.

        • Go to the following URL.
                              http://localhost:8080/PassiveSTSSampleApp
        • Now you will be redirected to Facebook Login page. Enter your Facebook credentials and you will be taken to the following page.



        REFERENCES

        Wednesday, April 9, 2014

        Login with Facebook for WSO2 Identity Server

        Nowadays we are using services form hundreds of websites. Most of these websites need the user to create an account providing a valid email address and password. For most people it is a nightmare to remember all the different user ids and passwords. To make the life easier most websites provide a user a option to login with Facebook Account, Twitter Account or Google Account. Since most of the internet users have one of these accounts it makes creating a new account instant.

        With WSO2 Identity Server 5.0 now users can login to Identity Server with their Facebook account. To do that first you have to create a Facebook app after registering as a Facebook developer.


        Step 1 : Configuring the Facebook App

        • Go to Apps > Create a New App

        • Enter an App Name and select an appropriate category and click on Create App. This will take you to the App Dashboard where you can find the AppID and AppSecret.

        • Go to Settings and click on Add platform 
        Click on website and configure as shown in the screenshot.


        • Go to Settings > Advanced
        Here you need to configure security settings as shown in the screenshot





        • Client OAuth Login should be set to Yes and OAuth redirect URL should be set to https://localhost:9443/commonauth .  Click on Save Changes button to save the changes.
        The app is not available to general public yet. To make to app available to every Facebook user, you have to submit the app for review. After a review Facebook make the app available to every Facebook user. More information on review process can be find by clicking on Status and Review.

        Because the review process is taking some time, you can specify some Facebook users as Developers or Testers. Only the specified here can use this app to Login with Facebook until the App go public.
        • Click on Roles to go the below page and specify the required Facebook users as Developers or Testers.


        Step 2 : Deploying  travelocity.com sample app


        Now you have finished configuring Facebook as an Identity Provider. Now you can configure IS to login to IS sample travelocity.com app using your Facebook credentials. 

        You can download travelocity.com.war file using the following link. 


        Deploy this sample web app on a web container. To do this, use the Apache Tomcat server. Since this sample is written based on Servlet 3.0 it needs to be deployed on Tomcat 7.x. Use the following steps to deploy the web app in the web container:


        Step 3 : Configuring Identity Provider

        Now you have to configure WSO2 Identity Server. First you need to download the latest version from
        • Extract the zip file and run wso2server.sh file inside the bin directory. (If you are using windows run wso2server.bat instead).
        • Login to the management console using
                                   URL :  https://localhost:9443/carbon/
                                   User Name : Admin                                        Password : Admin
        • In the Identity Section in the Main tab, click on Add button under Identity Providers.
        • Give a suitable name as the Identity Provider Name.



        • Go to Federated Authenticators > Facebook Configuration and enter the App ID and App Secret values form Facebook app into Client ID and Client Secret fields respectively.
        • Tick both check boxes to enable Facebook Authenticator and Make it the default. 

        Step 4 : Configuring Service Provider

        • Now go back to the WSO2 IS Management console. In the Manage Section in the Main tab, click on Add button under Service Providers.
        • Enter travelocity.com in the Service Provider Name text box and click Register. 
        • Click on Configure link under Inbound Authentication Configuration > SAML2 Web SSO Configuration.


        • Now set the configuration as follows:
                      Issuer : travelocity.com

                      Assertion Consumer URL : http://localhost:8080/travelocity.com/home.jsp

        • Check the following check-boxes :             
                      Enable Response Signing

                      Enable Assertion Signing

                      Enable Single Logout

                      Enable Attribute Profile

                      Include Attributes in the Response Always

        • Click on Update button to save the changes. Now you will be send back to the Service Providers page. 


        • Go to Local and Outbound Authentication Configuration.
        • Select the Identity Provider you created form the drop down under Federated Authentication. 
        • Select the Federated Authenticator option button and click Update button to save the changes. 

        Step 5 : Configuring claim mappings for Facebook.

        • In the Identity Section in the Main tab, click on List button under Identity Providers.
        • Click on the Edit button to edit the facebook identity provider. 
        • Go to Claim Configuration > Basic Claim Configuration
        • Select Define Custom Claim Dialect option under Select Claim mapping Dialect
        • Click on Add Claim Mapping to add custom claim mappings as follows. 

        • You can retrieve all the public information of the user and the email address. Here are some common attribute names. 

          • id
          • email
          • name
          • first_name
          • last_name
          • link
          • gender
          • locale
          • age_range
                  
        • More information is available from the following link.
                        https://developers.facebook.com/docs/facebook-login/permissions/v2.0


        • You can map these attributes to any Local Claim URI which you feels suitable. 


          Step 6 : Configuring requested claims for travelocity.com


          • In the Identity Section in the Main tab, click on List button under Service Providers.

          • Click on the Edit button to edit the travelocity.com service provider. 

          • Go to Claim Configuration 

          • Click on Add Claim URI  under Requested Claims to add the requested claims as follows. Here you should add the claims you mapped in the Identity Provider claim configuration. 



            • Select a suitable claim for the Subject Claim URI(Please not that email address cannot use without allowing using email addresses as user names in carbon.xml. To allow using email address as usernames uncomment <!--EnableEmailUserName>true</EnableEmailUserName--> in carbon.xml file inside wso2is-5.0.0/repository/conf)

            Now you have finished the configurations. To see the thing at work go to the following URL.




            • Click on : Click here to login with SAML from WSO2 Identity Server.
            Now you will be redirected to Facebook Login page. Enter your Facebook credentials and you will be taken to the home page of the travelocity.com app.



            Wednesday, November 20, 2013

            SonarQube analysis with Jacoco Ant task and Sonar Ant task

            SonarQube is a popular static code analysis tool. It has PMD, Findbugs and Checkstyle integrated by default. For code coverage, it uses Jacoco as the default. Most of the time in large projects which uses Ant as the build tool, It is easier to run SonarQube as a Ant task. Here I am going to describe the steps you need follow to get it done.

            SonarQube can be configured to use many database system. Here I have used MySQL. If you want to use another database system such as Oracle you can follow the same procedure. 

            First you need to install MySQL. Installation instructions can be found on http://dev.mysql.com/doc/refman/5.5/en/installing.html

            Log on to mysql

            mysql -u root -p

            Enter password if there is a one, if you didn't set up a password during the installation just press enter.

            You may need to delete the empty user first if you haven't done so yet.

            DELETE FROM mysql.user WHERE User='';

            Create a database to be used for Sonar. You can use any suitable name. I have used the name "SONARDB" here.

            CREATE DATABASE SONARDB CHARACTER SET utf8 COLLATE utf8_general_ci;

            Create a new database user SONARDB with password PASSWORD and grant all the privileges. Again you can choose any valid user name.

            grant all privileges on SONARDB.* to 'SONARDB'@'%' identified by 'PASSWORD';


            flush privileges;


            You can download SonarQube using the following link. For commercial applications it will be better to use a LTS version. The version I have used here is 3.5.1 ( http://dist.sonar.codehaus.org/sonar-3.5.1.zip). But this procedure should work for newer version also (At least up to 3.7, I haven't tested for later versions).

            http://www.sonarqube.org/downloads/


            Go to conf folder and open sonar.properties file. Only thing we need to configure here is the database connection information.

            Set sonar database username and password properties.

            sonar.jdbc.username:                       SONARDB
            sonar.jdbc.password:                       PASSWORD


            Uncomment the following line and change the db name form sonar to SONARDB

            sonar.jdbc.url:                            jdbc:mysql://localhost:3306/SONARDB?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true

            Go to bin folder. You can see several folders with several platform names. Select the one most suitable for your platform. ( For CentOS 6.4 64bit, Linux 32 bit Sonar worked without a problem )

            Start Sonar using following command.

                        sh sonar.sh start

            When the project is complex with several modules, it is easier to define sonar related configuration in separate files. Anyway for small projects you can define all the properties in the same build.xml. 

            First create a file named sonar-main.xml. This file will be the root of all sonar related configuration files.

            Download sonar-ant-task jar file using the following link and put it into the lib folder in your ant installation. sonar-ant-task-2.1.jar

            Download jacoco-ant-task jar file using the following link and put it into the lib folder in your ant installation. http://www.eclemma.org/jacoco/

            sonar-main.xml

            <?xml version="1.0" encoding="US-ASCII"?>

            <project name="sonar" default="sonar" xmlns:sonar="antlib:org.sonar.ant" >

                <property name="sonar.project.key" value="org.myproject"/>
                <property name="sonar.project.name" value="My Project"/>
                <property name="sonar.project.java.version" value="1.6"/>
                <property name="sonar.dir" value="${basedir}/target/sonar"/>
                <property name="sonar.host.url" value="http://localhost:9000"/>
                <property name="sonar.jdbc.url" value="jdbc:mysql://localhost:3306/SONARDB?useUnicode=true&amp;characterEncoding=utf8"/>
                 <property name="sonar.jdbc.driverClassName" value="com.mysql.jdbc.Driver"/>
                 <property name="sonar.jdbc.username" value="SONARDB"/>
                  <property name="sonar.jdbc.password" value="PASSWORD"/>
                 

                <target name="sonar" >

                    <taskdef uri="antlib:org.sonar.ant" resource="org/jacoco/ant/antlib.xml">
                        <!--&lt;!&ndash; Update the following line, or put the "jacocoant.jar" file in your "$HOME/.ant/lib" folder &ndash;&gt;-->
                        <classpath path="path/to/sonar/ant/task/lib/sonar-ant-task.jar" />
                    </taskdef>

                    <taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml">
                        <!--&lt;!&ndash; Update the following line, or put the "jacocoant.jar" file in your "$HOME/.ant/lib" folder &ndash;&gt;-->
                        <classpath path="path/to/jacoco/ant/task/lib/jacocoant.jar" />
                    </taskdef>

                    <property name="sonar.modules"
                              value="sdk/oranges/sonar-oranges.xml,sdk/apples/sonar-apples.xml"/>

                    <!-- The workDir directory is used by Sonar to store temporary files -->
                    <sonar:sonar key="${sonar.project.key}" version="${target.version}" xmlns:sonar="antlib:org.sonar.ant">

                        <!-- SERVER ON A REMOTE HOST -->
                        <property key="sonar.host.url" value="${sonar.host.url}"/>
                        <property key="sonar.jdbc.url" value="${sonar.jdbc.url}"/>
                        <property key="sonar.jdbc.driverClassName" value="${sonar.jdbc.driverClassName}"/>
                        <property key="sonar.jdbc.username" value="${sonar.jdbc.username}"/>
                        <property key="sonar.jdbc.password" value="${sonar.jdbc.password}"/>

                        <property key="sonar.java.source" value="${sonar.project.java.version}"/>
                        <property key="sonar.java.target" value="${sonar.project.java.version}"/>

                        <property key="sonar.build-stability.url" value="${sonar.host.url}"/>

                        <property key="sonar.projectName" value="${sonar.project.name}"/>

                        <property key="sonar.core.codeCoveragePlugin" value="jacoco" />
                        <property key="sonar.jacoco.reportPath" value="target/jacoco.exec" />

                        <property key="sonar.dynamicAnalysis" value="reuseReports"/>

                    </sonar:sonar>
                </target>

            </project>


            In each module, a xml file should be created with details about module name, locations of sources, binaries, test reports and other required properties.

            File name : sonar-oranges.xml
            Path  : sdk/oranges/sonar-oranges.xml

            <?xml version="1.0" encoding="US-ASCII"?>

            <project name="Oranges" default="all" basedir=".">

                <property name="sonar.java.source" value="1.6"/>
                <property name="sonar.java.target" value="1.6"/>
                <property name="sonar.projectKey" value="org.myproject"/>
                <property name="sonar.projectName" value="Oranges"/>
                <property name="sonar.sources" value="src/share"/>
                <property name="sonar.binaries" value="target/layout/WEB-INF/classes"/>
                <property name="sonar.tests" value="src/test"/>
                <property name="sonar.surefire.reportsPath" value="target/test/report" />
                <path id="lib.path">
                    <fileset dir="../../target/layout/core/lib">
                        <include name="**/*.jar"/>
                    </fileset>
                    <fileset dir="../../target/layout/tomcat/lib">
                        <include name="**/*.jar"/>
                    </fileset>
                </path>
                <pathconvert property="sonar.libraries" pathsep="," refid="lib.path" targetos="unix"/>

            </project>


            sonar.sources property should point to the directory where source files belonging to the module located.

            sonar.binaries should point to the directory where .class files belonging to the module located.

            sonar.tests should point to the directory where Junit test files located.

            sonar.surefire.reportsPath property should point to the directory where Junit xml test reports are created after executing the test cases. Sonar uses these reports to display details of test execution in the dashboard.

            A target should be defined in the main build.xml file pointing to  sonar-main.xml file.

            <target name="run-sonar" depends="sonar-clean">
                <ant antfile="sonar-main.xml" target="sonar"/>
            </target>



            To analyse code coverage with Jacoco, it is required to run Unit tests with Jacoco agent. There are two methods to add Jacoco agent to the unit tests. 

            Method 1: 

            If you plan to run Jacoco agent every time units tests are run, this method can be used. 

            <!-- Run your unit tests, adding the JaCoCo agent -->
            <jacoco:coverage destfile="target/jacoco.exec" xmlns:jacoco="antlib:org.jacoco.ant">
                <junit fork="yes" dir="${basedir}" failureProperty="test.failed">
                    <classpath location="${classes.dir}" />
                    <classpath refid="classpath" />
                    <formatter type="xml" />
                    <batchtest todir="${reports.junit.xml.dir}">
                        <fileset dir="${test.dir}">
                            <include name="**/*Test.java" />
                        </fileset>
                    </batchtest>
                </junit>
            </jacoco:coverage> 


            Method 2: 

            If you do not want to run Jacoco agent every time the tests are running, you can use this method. This method will be more useful than the earlier method, because running Jacoco agent will increase the running time of test cases.


            First you use the value of run-coverage property to decide whether or not to pass Jacoco agent as a JVM argument.

            <if>
                <equals arg1="${run-coverage}" arg2="true"/>
                <then>
                    <jacoco:agent property="agentvmparam" destfile="target/jacoco.exec"
                                          xmlns:jacoco="antlib:org.jacoco.ant"/>
                </then>
                <else>
                    <property name="agentvmparam" value=""/>
                </else>
            </if>


            If the run-coverage property is set to true, Jacoco agent will be passed as a JVM argument. Otherwise it will pass a empty value for agentvmparam.


            <junit fork="yes" dir="${basedir}" failureProperty="test.failed">
                                   
                <!-- Run unit tests, adding the JaCoCo agent -->
                <jvmarg line="${agentvmparam}"/>
                <classpath location="${classes.dir}" />
                <classpath refid="classpath" />
                <formatter type="xml" />
                <batchtest todir="${reports.junit.xml.dir}">
                    <fileset dir="${test.dir}">
                        <include name="**/*Test.java" />
                    </fileset>
                </batchtest>
            </junit>

            You can set the parameter value only when running test cases to collect coverage data by using "antcall".

            <target name="run-coverage">             
                <antcall target="test">
                    <param name="run-coverage" value="true"/>
                </antcall>
            </target>



            Wednesday, November 13, 2013

            Jenkins Testlink Integration

            What is Jenkins

            Jenkins is a popular open source continuous integration tool written in Java. You can find more information form http://jenkins-ci.org/.



            What is TestLink

            TestLink is an open source test management system written in PHP. If you need you can find more information at http://testlink.org/.


            Jenkins TestLink Integration

            We can use Jenkins TestLink plugin to integrate Jenkins and TestLink  products. If we run unit tests in a Jenkins build job we can use the plugin to publish unit test results in TestLink. Following tutorial explain how to do that https://wiki.jenkins-ci.org/download/attachments/753702/jenkins.pdf

            But sometimes it is not practical to run unit tests in a Jenkins build. In those situations we enter the test execution data manually to TestLink and then configure the plugin to read those information form there. We can configure Jenkins to pass, fail or mark the build as unstable depending on the test results read from TestLink.

            First you have to install Jenkins TestLink plugin. To do that

            1) Go to Manage Jenkins > Manage Plugins
            2) Click the Available tab
            3) Select Jenkins TestLink Plugin
            4) Click Install without restart button.

            Then you have to configure Build Job to fetch test results form Testlink.

            1) Click on the Job name you want to configure and go to Configure.
            2) Under Build, click Add action button and select Invoke TestLink action.



            3) Fill the fields according to your Testlink configuration. You have to specify the Build Name you need to fetch test results from.
            4) Click Advanced button under Test Execution. Here you can configure whether it is required to fail the build when test cases are failed or not.


            You can find out how to configure Testlink by reading Jenkins Testlink Plugin Tutorial ( https://wiki.jenkins-ci.org/download/attachments/753702/jenkins.pdf.)  I have used following Jenkins and Testlink versions in this post.

            Jenkins Version   : 1.536
            TestLink Version : 1.9.8
            Jenkins Testlink Plugin Version : 3.7