Saturday, February 02, 2019

Tech links



How to use GitHub:
https://guides.github.com/activities/hello-world/


API authentication using AWS Cognito
https://gist.github.com/faermanj/abc31d2fefca6701e87a9e3a9e885c18

Static link mentioned in the link above - it is broken if you click from aboce link, so paste it directly
https://gist.github.com/faermanj/bf35079ad64cbbb5bfa85f1878ad023c

Video links that explains above link on AWS Cognito
https://aws.amazon.com/cognito/getting-started/

Sunday, April 22, 2012

Working with PowerPoint Presentation using Java

The article shows how to work with PowerPoint presentation in Java using simple scripting language. Though open source from Apache POI supports working with PowerPoint presentations; but it has its own limitations.

Disadvantage  with Open source Apache POI-HSLF and POI-XLSF:
-         POI still in early development and is a subject
to incompatible changes in future.
-         Current version of POI (POI-HSLF and POI-XSLF)
supports only implementation of Powerpoint
2007 format.
-         HSLF and XSLF though has similar features, the
interface among them is not common; making maintenance difficult; if same
feature need to be provided in different format.
-         POI provides API  at very elementary level. For a task
as easy as copying a slide from one presentation to another presentation;
requires hundreds of lines of code and makes maintenance difficult.
-         We didn’t find even Jpeg conversions of powerpoint an easy task with POI.

A better option is use to the scripting provided by Microsoft itself and to use it within Java for powerpoint presentation. We have chosen to use vb script and run it using cscript (a command line version of wscript). One of the advantages with cscript over other types of programming is that for cscript,
everything you need is built into the Windows operating system.
It is easy and doesn’t need any installation. Though it makes programming platform dependent; but it make sense; after all; we are going to use MSOffice on Windows machines only.

We would now take few examples of writing VB script for routine work required with powerpoint
presentations:

a)  Example of VB Script for copying a slide from one presentation to end of another presentation

Set pptDoc = CreateObject("PowerPoint.Application")
pptDoc.Visible = TRUE
Set objPresentation = pptDoc.Presentations.Open("D:\Workspace\vbscript\ppt\MyPresentationTo.pptx")
objPresentation.Slides.InsertFromFile _
"D:\Workspace\vbscript\ppt\MyPresentationFrom.pptx",objPresentation.Slides.Count , 1, 1
objPresentation.Save
objPresentation.close
pptDoc.Quit

Open method in above example opens presentation “MyPresentationTo.pptx” in which slide is
to be copied.  InsertFromFile method copies one slide from “MyPresentationFrom.pptx” at the end of
MyPresentationTo.pptx”.

First argument of InsertFromFile specifies the name of presentation from which slides are to be copied. Second argument specifies the index after which you want to insert the copied slides in the opened presentation. Third argument specifies the index of first slide that you want to copy from presentation. Fourth argument specifies the index of last slide that you want to copy from presentation.

After copying slide; we saved the file and closed the presentation within script.
To try this; copy above example in a notepad; save it as “.vbs extention
e.g. “CopySlide.vbs” and double click on it. Remember to create two ppt (MyPresentationTo.pptx, MyPresentationFrom.pptx) in the specified folder before executing script.

b)  Following example of VB Script shows how to add shapes to a slide:

Set pptDoc = CreateObject("PowerPoint.Application")
pptDoc.Visible = TRUE
Set objPresentation = pptDoc.Presentations.Open("D:\Workspace\vbscript\ppt\MyPresentationTo.pptx")
Set myDocument = objPresentation.Slides(1)
Set line = myDocument.Shapes.AddLine(40, 40, 80, 80)
objPresentation.Save
objPresentation.close
pptDoc.Quit

AddLine method  in above example adds a line to Slide 1 in above example.


c)  Following example shows how to export a presentation in jpg format:
    Set pptDoc = CreateObject("PowerPoint.Application")
    pptDoc.Visible = TRUE
   Set objPresentation = pptDoc.Presentations.Open 
    ("D:\Workspace\vbscript\ppt\MyPresentationTo.pptx")
   Set myDocument = objPresentation.Slides(1) myDocument.Export  
    "D:\Workspace\vbscript\ppt\MyPresentation.jpg","JPG"
    objPresentation.Save
   objPresentation.close
   pptDoc.Quit

Export command in above program exports presentation to jpg format. First argument to the method is the path where to export the file and second argument is the format in which presentation is to be exported.

Once you have learnt and played with scripts; you can write a small program to execute these scripts
from Java.
import java.io.IOException;
public class RunScript {
  public static void main (String args[]) throws IOException {
    if (args == null || args.length == 0) {
      System.out.println("Usage: java RunScript <scriptfile>" );
      System.exit(1);
    }
    runScript(args[0]);   
  }

  public static void runScript(String script) throws IOException {
    String command = "cmd /c cscript " + script;
    Runtime.getRuntime().exec(command);
  }
}

 
In above example you may call runScript method from any of your program.

 E.g. the script shown in example a) above was stored as “Copy Slide.vbs” and executed using following
command after compilation:
java RunScript  D:\Workspace\vbscript\scripts\CopySlide.vbs

It copied Slide 1 from  MyPresentationFrom.pptx at the end of MyPresentationFrom.pptx

The real power lies in making the script dynamic thru Java programming and then using it at runtime. Though this article has been focused on PowerPoint presentations; but you may use this technique with MSWord and MSExcel as well.

Advantage:
-         Provides code compatibility among various versions
of MSOffice
-         Easy to use commands
-         Tasks like copying slides and exporting can be
done within few lines of code.

Limitation:
-         Not compatible over platform

Friday, January 13, 2012

Audit Trail using log4j



Audit trail is used in most of the applications to track the activities performed by a user (e.g. resources accessed or changes made within the system). Audit trails of applications are generally stored in the database; as they require filtering based on different attributes like userid, date/time, activity etc. and sometime the logs are required to generate reports.

Traditional approach with in java application for audit trailing is to use jdbc. This approach is not only cumbersome but has few pitfalls. E.g. the audit feature cannot be switched off unless the application has been designed to do so. Similarly; a product may require different level of audit logs depending upon the environment where it is being implemented. E.g. an application deployed for guest user may not require auditing at all but same application if installed in a high secured zone may require very fine level of auditing.

With traditional approach of using jdbc; application can audit logs only in database. The application may require logging the audit trails to multiple locations (e.g. to file system/ console) apart from database.  While maintenance; it may even be required to know from which class the audit message has been generated. Traditionally a log (using log4j or java logging api) is written before/after making jdbc call to record audit in database. But it is at the mercy of developer if has written such code while auditing each log.

 Since most of the features mentioned above comes inherent with logging APIs such as log4j. It would be a good idea to use such logging API itself for auditing as well.

This article would use log4j for logging audit trail and mysql as database for storing them.

Let’s first define the information we want our application to capture for auditing purpose. Say we want to maintain audit id, user id, timestamp, audit level, activity and activity detail in our audit. We would create our audit table in the database using following sql statement:

CREATE TABLE AUDIT(
    AUDIT_ID INT PRIMARY KEY AUTO_INCREMENT,
    USER_ID VARCHAR(50),
    TIMESTAMP TIMESTAMP,
    LEVEL   VARCHAR(5),
    ACTIVITY VARCHAR(50),
    ACTIVITY_DETAIL VARCHAR(1000)
 );

Since AUDIT_ID is a auto generated column and information regarding TIMESTAMP and LEVEL can be provided log4j; hence our code needs not to take these columns into account. We only need to consider how to pass application level information like userid, activity and activity detail to logger.

It would be a good idea to create a wrapper over Logger that can take care of passing all the application level information like userid, activity etc. to logger.

Let’s create a class that would encapsulate logger and would act our one stop point for auditing.


package myapplication.audit;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.MDC;


public class AuditLogger {
      public static void debug (String userid, String activity,
String activityDetail) {
   …
}    

public static void info (String userid, String activity,
String activityDetail) {
               …
}

You may create other methods for different log levels. In case mutilple log levels are not required in your application; you may create single method with name audit.

We are going to use two features of Log4J: MDC and FQCN. Mapped diagnostic context (MDC) would be used to add additional information like user id and activity to the logs.

package myapplication.audit;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.MDC;


public class AuditLogger {
      
       private static String FQCN"myapplication.audit.AuditLogger";
      
       public static void info (String userid, String activity, String activityDetail) {
              MDC.put("userid", userid);
              MDC.put("activity", activity);
              Logger.getLogger(AuditLogger.class.getName()).log(FQCN, Level.INFO,  activityDetail, null);
              MDC.clear();
       }
       …
}
Please note we have shown a method with the name info() which logs audit trail with level INFO. We can have additional methods with others log levels as well.

Additional information like userid and activity has been passed by application to the logger using MDC. Once the information has been audited; the information has been later on cleared using clear() method of MDC.

We have configured JDBCAppender and configured database information along with SQL statement to insert audit trail in the database. Please note JDBCAppender doesn’t require PatternLayout.

xml version="1.0" encoding="UTF-8"?>
DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

       <appender name="FILE" class="org.apache.log4j.RollingFileAppender">
              <param name="File" value="logs/audit.log">param>
              <param name="Append" value="true">param>
              <layout class="org.apache.log4j.PatternLayout">
                     <param name="ConversionPattern"
                           value="%d %-5p [%t] %C{3} (%F:%L) - %m%n">param>
              layout>
       appender>
      
       <appender name="DB" class="org.apache.log4j.jdbc.JDBCAppender">
              <param name="URL" value="jdbc:mysql://localhost/auditschema"/>
              <param name="driver" value="com.mysql.jdbc.Driver"/>
              <param name="user" value="root"/>
              <param name="password" value="admin"/>
              <param name="sql" value="INSERT INTO AUDIT(USER_ID, TIMESTAMP, LEVEL, ACTIVITY, ACTIVITY_DETAIL) VALUES('%X{userid}','%d{yyyy-MM-dd HH:mm:ss.SSS}','%p', '%X{activity}', '%m')"/>
      
       appender>

       <appender name="NULL" class="org.apache.log4j.varia.NullAppender">appender>
      
       <category  name="myapplication.audit">
              <priority value="DEBUG">priority>
              <appender-ref ref="FILE">appender-ref>
              <appender-ref ref="DB">appender-ref>
       category>
       <category  name="myapplication.test">
              <priority value="DEBUG">priority>
              <appender-ref ref="FILE">appender-ref>
       category>
      
       <root>
              <priority value="off">priority>
              <appender-ref ref="NULL">appender-ref>
       root>
      
log4j:configuration>

Please note we have defined separate category for audit “myapplication.audit” within log4j configuration. Further all the loggers have been created using “AuditLogger.class.getName()” e.g. Logger.getLogger(AuditLogger.class.getName()) where the value of AuditLogger.class.getName() is “myapplication.audit.AuditLogger”. Configuring a category with “myapplication.audit” would allow switching off audit logs if required.

Create a program to test auditing.

package myapplication.test;

import myapplication.audit.AuditLogger;

import org.apache.log4j.Logger;


public class TestAudit {
   public static void main (String args[]) {
         Logger.getLogger(TestAudit.class).debug("Before audit");
         AuditLogger.info("ashutosh","accesed", "User edit page");
         Logger.getLogger(TestAudit.class).debug("after audit");
   }
}


Compile it and execute it. Below is the output from mysql on querying audit table.
mysql> select * from audit;



Below are the logs shown from file after compiling and running the program.

2012-01-12 16:04:21,538 DEBUG [main] myapplication.test.TestAudit (TestAudit.java:10) - Before audit
2012-01-12 16:04:21,541 INFO  [main] myapplication.test.TestAudit (TestAudit.java:11) - User edit page
2012-01-12 16:04:21,767 DEBUG [main] myapplication.test.TestAudit (TestAudit.java:12) - after audit

Please note the output for both application log and audit has been redirected to file. This way you can easily track application logs and audit from same place.  We can also see the value of caller issuing the logging request is “myapplication.test.TestAudit” instead of “myapplication.audit.AuditLogger”; it has been achieved by using FQCN.

Logger.getLogger(AuditLogger.class.getName()).log(FQCN, Level.INFO,  activityDetail, null);

This method allows logging messages from a wrapper class.

Wednesday, October 12, 2011

Securing applications and web services thru JOSSO

Centralized authentication ensures that users do not actively have to enter their credential to open multiple application in same organization.

JOSSO, or Java Open Single Sign-On, is an open source J2EE-based SSO infrastructure aimed to provide a solution for centralized platform neutral user authentication. JOSSO is open source and is commercial friendly.  JOSSO exposes Single Sign On services using SOAP over HTTP protocol allowing it to easily integrate with non-Java applications and soap client.  Josso support validation of credentials stored in mutilple formats like Database/XML/Ldap etc.

There are further needs in applications to even make webservices SSO enabled. To enable webservice sso enabled the SSO session id is set in all the requests by a custom Axis client side cookie handler.  All requests are then intercepted by the JOSSO Agent which interacts with the JOSSO Gateway to get the authentication/authorization of the request based on the SSO session id.

How JOSSO works?

JOSSO comprises three main components:

SSO Gateway (IdP): SSO server, also known as Identity Provider, responsible of acting as a web access management authority for SSO-enabled applications and their users.

SSO Agent: Handles the single sign-on use-cases and execution environment integration details for SSO-enabled applications. Agents consume Gateway identity services.

Partner application (SP): SSO-enabled web application, also known as Service Provider that relies on the SSO Agent and Gateway components for providing the Single Sign-On experience to users.

 Interaction between components

a)      User requests for web resource using browser

b)      SSO Agent interrupts the request and checks if resource is protected and is for partner application

c)       SSO Agent checks if SSO session is present using JOSSO_SESSION_ID

d)      If SSO session is not present; SSO agent submits authentication request to gateway. If SSO session is present; agent sends SSO session assert request to gateway to test if user is not already logout thru another application.

e)      Gateway checks if SSO session is present using JOSSO_SESSION_ID.

f)       If SSO session is not present; user credentials are requested by showing login form.

g)      If credentials are invalid user is again requested for credentials till max retries.

h)      If credentials are valid SSO session is created on gateway and assertion details (i.e. authentication/ authorization details) are sent to agent. On assertion resolution session is created on agent; security is associated with the token and security context is injected.

i)        Resource access is then provided to the user.

 

Steps for enabling SSO for an application using JOSSO:

For authenticating using JOSSO gateway and agent :

-       Install JOSSO Gateway

-       Configure LDAP authenticator and identity manager to point to LDAP server on JOSSO gateway

-       Install JOSSO agent on the tomcat server which would host the Web application

-       Configure JOSSO agent

 

Install JOSSO Gateway:

Prerequisites:

a)      JDK 1.5 or above

b)      Tomcat 6.0 or any other App server

c)       JOSSO binaries

JOSSO 1.8 comes with JOSSO deployment console that helps install JOSSO components (Gateway and Agents). The console has been implemented using Apache Geronimo GShell. GShell is an extensible, command-line processing environment for creating platform independent command-line applications.

To install JOSSO Gateway; start “JOSSO gshell” using josso-gsh.bat (on Windows environemnt) or josso-gsh.sh (on UNIX variants).

Use following command to install “JOSSO gateway”: 

gateway install -t <Target installation directory> --platform <app server>

e.g. to install JOSSO gateway on tomcat 6.0 in “/opt/apache-tomcat-6.0.18” directory

josso> gateway install -t /opt/apache-tomcat-6.0.18 --platform tc60

e.g. to install JOSSO gateway on tomcat 6.0 in “/opt/apache-tomcat-6.0.18” directory with default ldap configuration

josso> gateway install -t /opt/apache-tomcat-6.0.18 --platform tc60 --persistence ldap

The install process performs the following tasks:

1.        Verify that the selected target matches the selected installer / platform.

2.        Generates and installs the 'AES' key used by the automatic authentication

3.        Installs default gateway configuration

4.        Deploys the JOSSO gateway war (josso.war)

Configure LDAP authenticator and identity manager to point to LDAP server on JOSSO gateway

The following configuration shows authentication thru ldap. Similarly JOSSO can be configured for authentication with database or XML.

 Using this configuration JOSSO is told to import the josso-gateway-ldap-stores.xml XML configuration file and define the bind authentication bean.

Modify josso-gateway-config.xml to point to ldap store.

josso-gateway-config.xml

<?xml version="1.0" encoding="ISO-8859-1" ?>
<s:import resource="josso-gateway-ldap-stores.xml" />
 
    <def-auth:authenticator id="josso-authenticator">
        <def-auth:schemes>
                     <s:ref bean="josso-bind-authentication"/>
        </def-auth:schemes>
    </def-auth:authenticator>

 

Configuring the LDAP Store

The josso-gateway-ldap-stores.xml contains the configuration for connecting to the LDAP server

    <ldap-istore:ldap-bind-store
            id="josso-identity-store"
                        class="org.josso.gateway.identity.service.store.ldap.LDAPBindIdentityStore"
            initialContextFactory="com.sun.jndi.ldap.LdapCtxFactory"
            providerUrl="ldap://10.145.130.86:1420/"
            securityPrincipal="uid=queryuser,ou=People,dc=xyz"
            securityCredential="xxxx"
            securityAuthentication="simple"
            ldapSearchScope="SUBTREE"
            usersCtxDN="ou=People,dc=xyz"
            principalUidAttributeID="uid"
            uidAttributeID="uniqueMember"
            rolesCtxDN="ou=Roles,ou=a,dc=xyz"
            roleAttributeID="cn"
            />

Configuring the Authenticator

The configuration for authenticator is specified in the josso-gateway-auth.xml configuration file. This component is responsible for authenticating the user using the configured authenticator and managing the authenticated user sessions. The id defined in ldap store need to be configured in authenticator

<?xml version="1.0" encoding="ISO-8859-1" ?>
<bind-authscheme:bind-auth-scheme
            id="josso-bind-authentication"
            name="basic-authentication"
            hashAlgorithm="MD5"
            hashEncoding="HEX"
            ignorePasswordCase="false"
            ignoreUserCase="false">
                        
        <bind-authscheme:credentialStore>
            <s:ref bean="josso-identity-store"/>
        </bind-authscheme:credentialStore>
 
        <bind-authscheme:credentialStoreKeyAdapter>
            <s:ref bean="josso-simple-key-adapter"/>
        </bind-authscheme:credentialStoreKeyAdapter>
    </bind-authscheme:bind-auth-scheme>
 

Configuring Login Form

Login form can be configured in josso-gateway-web.xml by modifying costomLoginURL. Point to the login page; you want to show during login.

<web-configuration id="josso-web-configuraiton"

                       rememberMeEnabled="true"

                       sessionTokenOnClient="true"

                       sessionTokenSecure="false"

                       sendP3PHeader="false"

                 customLoginURL="http://localhost:8080/partnerapp/partner-login.jsp">

 

Agent install:

To install JOSSO Gateway; open “JOSSO gshell” using josso-gsh.bat (on Windows environemnt) or josso-gsh.sh (on UNIX variants).

Use following command to install “JOSSO gateway”: 

        agent install –t <target installation directory>  --platform <app server>

 

e.g. to install JOSSO agent on tomcat 6.0 in “/opt/apache-tomcat-6.0.18” directory

 

josso> agent install –t /opt/apache-tomcat-6.0.18 --platform tc60

 

The install process performs the following tasks:

1.       Verifies that the target platform matches the selected installer / platform.

2.       Installs 3rd party JARs needed by JOSSO Agent

3.       Installs Agent components

4.       Installs Agent configuration resources

5.       Configures the Container (when possible)

 

CONFIGURE JOSSO AGENT

The main responsability of the Single Sign-On Agent is to check that a previously user logged in through the Single Sign-On Gateway is authorized to access a web context.

The Agent verifies this information by querying via SOAP the Single Sign-on webservice infrastructure using a special cookie set by the Single Sign-On Gateway on authentication.

Add this xml snippet to josso-agent-config.xml to make the web application a partner application to JOSSO. Please change the id and context as required.

<agent:partner-app id="partnerapp " context="/partnerapp">

<ignore-web-resource-collections>public-resources,img-resources</ignore-web-resource-collections>

 </agent:partner-app>

<agent:partner-app id="partnerapp2 " context="/partnerapp2">

<ignore-web-resource-collections>public-resources,img-resources</ignore-web-resource-collections>

 </agent:partner-app>

 

 

Configure the SSO Gateway login URL

The Single Sign-On Agent Configuration must reside in the $CATALINA_HOME/lib directory and should be referenced by the josso-agent-config.xml file as stated before.

<?xml version="1.0" encoding="UTF-8" ?>
        <gatewayLoginUrl>http://localhost:8080/josso/signon/login.do</gatewayLoginUrl>
        <gatewayLogoutUrl>http://localhost:8080/josso/signon/logout.do</gatewayLogoutUrl>
  <configuration>
      <agent:agent-configuration>
         </agent:partner-app>
             <agent:partner-app id="partnerap" context="/ partnerapp">
                   <ignore-web-resource-collections>public-resources,img-resources</ignore-web-resource-collections>
              </agent:partner-app>
             </agent:partner-apps>
         </agent:agent-configuration>
   </configuration>
        

Using this configuration one can set:

  • The Gateway Login URL, where the Single Sign-On Agent will redirect the user on protected resource access request so that he can authenticate.
  • The Gateway Logout URL, where the Single Sign-On Agent will redirect the user on logout request.
  • Concrete Single Sign-On Agent to be instantiated
  • The concrete Service Locator to be used to invoke the services of the Single Sign-On Gateway.

In this specific case, which is the default, is using SOAP over HTTP to invoke The Single Sign-On Gateway WebServices.

If the gateway and the agent are running in the same server this will be localhost and the port should be the port where Tomcat is listening for incoming HTTP requests.

Set up Security Constraints (JEE)

Web application Security Constraints (web.xml) of your application

<security-constraint>

  <web-resource-collection>

    <web-resource-name>public-resources</web-resource-name>

    <url-pattern>/lib/*</url-pattern>

    <http-method>HEAD</http-method>

    <http-method>GET</http-method>

    <http-method>POST</http-method>

    <http-method>PUT</http-method>

    <http-method>DELETE</http-method>

  </web-resource-collection>

</security-constraint>

<security-constraint>

  <web-resource-collection>

    <web-resource-name>protected-resources</web-resource-name>

    <url-pattern>/*</url-pattern>

    <http-method>HEAD</http-method>

    <http-method>GET</http-method>

    <http-method>POST</http-method>

    <http-method>PUT</http-method>

    <http-method>DELETE</http-method>

  </web-resource-collection>

    <auth-constraint>

    <role-name>*</role-name>

  </auth-constraint>

  <user-data-constraint>

    <transport-guarantee>NONE</transport-guarantee>

  </user-data-constraint>

</security-constraint>

<login-config>

  <auth-method>FORM</auth-method>

  <form-login-config>

    <form-login-page>/login-redirect.jsp</form-login-page>

    <form-error-page>/login-redirect.jsp</form-error-page>

  </form-login-config>

</login-config>

 

You are ready with an SSO enable application. Similarly configure your other applications.

 

Making Web Services SSO/JOSSO enabled

To make your webservices application JOSSO enabled. The webservice client would require passing JOSSO session id with each webservice request.

COOKIE HANDLER

A custom axis client side handler which sets the SSO session id in all the requests made by the client.

client-config.wsdd

 

<?xml version="1.0" encoding="UTF-8"?>

<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">

<globalConfiguration>

<requestFlow>

<handler type="CookieHandler"/>

</requestFlow>

</globalConfiguration>

<transport name="http" pivot="java:org.apache.axis.transport.http.HTTPSender"/>

</deployment>

 

CookieHandler.java

 

import org.apache.axis.AxisFault;

import org.apache.axis.MessageContext;

import org.apache.axis.handlers.BasicHandler;

import org.apache.axis.transport.http.HTTPConstants;

 

public class CookieHandler extends BasicHandler {

public void invoke(MessageContext context) throws AxisFault {

String cookieValue = System.getProperty("josso_session_id");

context.setProperty(HTTPConstants.HEADER_COOKIE, “JOSSO_SESSION_ID” + "=" + cookieValue);

context.setMaintainSession(true);

      }

}