Sunday 9 October 2011

Sample Code for CredentialVaultService

In this Example,we are going to do SSO with a plain J2EE Applications from Portal using CredentialVaultService.

Develop Plain J2EE Application:


  •  After entering the credentials
Develop  CredentialVaultPortlet

Vault Slots 

Using Credential Service, we can create two types of Vault Slots in user-managed vault segments.
  • A shared user slot stores user credentials that are shared among the user's portlets. It is a shared slot that belongs to the user segment. This slot type can be created through the Credential Vault portlet service by using the appropriate method and setting the argument as true for shared slot. 
  • A portlet private slot stores user credentials that are not shared among portlets. It is an unshared slot that belongs to the user segment. This slot type can be created through the Credential Vault portlet service by using the appropriate method and setting the argument as false for shared slot.
Shared User - one secret per user and portlet entity - not shared among portlets
Portlet Private Slot- one secret per user and portlet entity - not shared among portlets

Credential objects
There are two types credential objects available in websphere portal server.
  • Passive credential objects are containers for the credential's secret. Portlets that use passive credentials need to extract the secret from the credential and do all the authentication communication with the backend itself.
      /*
       * The following method extracts userid and password from the slot and sets in StringBuffer
       */
      private void getCredential(RenderRequest request,StringBuffer userid, StringBuffer password) {
            try{
                  String slotId = getSharedSlotId(request);

            if(slotId==null)
                  return ;

            UserPasswordPassiveCredential credential =(UserPasswordPassiveCredential) vaultService.getCredential
                                    (slotId, "UserPasswordPassive", new HashMap<String,String>(), request);
                  userid.append(credential.getUserId() );
                  password.append( String.valueOf(credential.getPassword() ) );
            }
            catch(Exception  e){
                  return ;
            }
      }
  • Active credential objects hide the credential's secret from the portlet; there is no way of extracting it out of the credential. In return, active credential objects offer business methods that take care of all the authentication
      if (slot != null)
            {
                  HttpFormBasedAuthCredential credential;
                  try {
                        credential = (HttpFormBasedAuthCredential) vaultService.getCredential(slot,CredentialTypes.HTTP_FORM_BASED_AUTH, buildCredentialConfigurationMap(), request);
                        //login to the resource
                        credential.login();
                        HttpURLConnection infoConn = credential.getAuthenticatedConnection("http://localhost:10039/Login/TestServlet");
                        InputStream is = infoConn.getInputStream();
                        String info = readStringFromStream(is);
                        //credential.logout();
                        request.setAttribute("result",info);
                       
                  } catch (CredentialVaultException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                  }
                   catch (Exception e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                        }
            }
In view mode, using credential valut service we are doing sso with Login Application and results are displayed. From doing SSO, active credential type is used.



On click "Configuration Settings",it enters into edit mode.In Edit mode, configuration of userid and password is done. Deletion of slot is also done.

 
Final result
Sample Code:

package com.ibm.mycredentialservice;
import java.io.*;
import java.net.HttpURLConnection;
import java.util.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.portlet.*;
import com.ibm.portal.ObjectID;
import com.ibm.portal.PortletSecretManager;
import com.ibm.portal.portlet.service.PortletServiceHome;
import com.ibm.portal.portlet.service.credentialvault.CredentialSlotConfig;
import com.ibm.portal.portlet.service.credentialvault.CredentialTypes;
import com.ibm.portal.portlet.service.credentialvault.CredentialVaultException;
import com.ibm.portal.portlet.service.credentialvault.CredentialVaultService;
import com.ibm.portal.portlet.service.credentialvault.credentials.HttpFormBasedAuthCredential;

/**
 * A sample portlet based on GenericPortlet
 */
public class MyCredentialServicePortlet extends GenericPortlet {
    private static CredentialVaultService vaultService = null;
    private static String sharedSlotResourceName ="loginslot";
    public static final String JSP_FOLDER    = "/_MyCredentialService/jsp/";    // JSP folder name
    public static final String VIEW_JSP      = "MyCredentialServicePortletView";         // JSP file name to be rendered on the view mode
    public static final String EDIT_JSP      = "MyCredentialServicePortletEdit";         // JSP file name to be rendered on the edit mode
    public static final String SET_PRIVATE_CV_ACTION = "SetPrivateCV";
    public static final String DELETE_PRIVATE_CV_ACTION = "DeletePrivateCV";
    public static final String CV_USERID = "CVUserID";
    public static final String CV_PASSWORD = "CVPassword";
    public static final String CV_SUBMIT = "CVSubmit";
    /**
     * @see javax.portlet.Portlet#init()
     */
    public void init() throws PortletException{
        super.init();
        Context context;
        try {
            context = new InitialContext();
            PortletServiceHome vaultServiceHome = (PortletServiceHome)context.lookup("portletservice/com.ibm.portal.portlet.service.credentialvault.CredentialVaultService");
            if(vaultServiceHome != null)
                vaultService = (CredentialVaultService)vaultServiceHome.getPortletService(com.ibm.portal.portlet.service.credentialvault.CredentialVaultService.class);
        } catch (NamingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
       
    }

    /**
     * Serve up the <code>view</code> mode.
     *
     * @see javax.portlet.GenericPortlet#doView(javax.portlet.RenderRequest, javax.portlet.RenderResponse)
     */
    public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException {
        // Set the MIME type for the render response
        response.setContentType(request.getResponseContentType());
        String slot = getSharedSlotId(request);
        if (slot != null)
        {
            HttpFormBasedAuthCredential credential;
            try {
                credential = (HttpFormBasedAuthCredential) vaultService.getCredential(slot,CredentialTypes.HTTP_FORM_BASED_AUTH, buildCredentialConfigurationMap(), request);
                //login to the resource
                credential.login();
                HttpURLConnection infoConn = credential.getAuthenticatedConnection("http://localhost:10039/Login/TestServlet");
                InputStream is = infoConn.getInputStream();
                String info = readStringFromStream(is);
                //credential.logout();
                request.setAttribute("result",info);
               
            } catch (CredentialVaultException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
             catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        }
        // Invoke the JSP to render
        PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(getJspFilePath(request, VIEW_JSP));
        rd.include(request,response);
    }

    private String readStringFromStream(InputStream is) throws IOException
    {
        String info;
        StringWriter writer = new StringWriter();
        int rc = 0;
        int bufferSize = 4096;
        byte[] buffer = new byte[bufferSize];
        rc = is.read(buffer);
        writer.write(new String(buffer).substring(0, rc));
        info = writer.getBuffer().toString();
        return info;
    }
    /**
     * Serve up the <code>edit</code> mode.
     *
     * @see javax.portlet.GenericPortlet#doEdit(javax.portlet.RenderRequest, javax.portlet.RenderResponse)
     */
    public void doEdit(RenderRequest request, RenderResponse response) throws PortletException, IOException {
        // Set the MIME type for the render response
        response.setContentType(request.getResponseContentType());

        // Invoke the JSP to render
        PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(getJspFilePath(request, EDIT_JSP));
        rd.include(request,response);
    }
   
    /**
     * Returns JSP file path.
     *
     * @param request Render request
     * @param jspFile JSP file name
     * @return JSP file path
     */
    private static String getJspFilePath(RenderRequest request, String jspFile) {
        String markup = request.getProperty("wps.markup");
        if( markup == null )
            markup = getMarkup(request.getResponseContentType());
        return JSP_FOLDER + markup + "/" + jspFile + "." + getJspExtension(markup);
    }

    /**
     * Convert MIME type to markup name.
     *
     * @param contentType MIME type
     * @return Markup name
     */
    private static String getMarkup(String contentType) {
        if( "text/vnd.wap.wml".equals(contentType) )
            return "wml";
        else
            return "html";
    }

    /**
     * Returns the file extension for the JSP file
     *
     * @param markupName Markup name
     * @return JSP extension
     */
    private static String getJspExtension(String markupName) {
        return "jsp";
    }

    /**
         * Process an action request.
         *
         * @see javax.portlet.Portlet#processAction(javax.portlet.ActionRequest, javax.portlet.ActionResponse)
         */
public void processAction(ActionRequest request, ActionResponse response) throws PortletException, java.io.IOException {
    try {
    if( request.getParameter(SET_PRIVATE_CV_ACTION) != null ) {
        System.out.println("Entering ino processAction");
       
        // Set userId/password text in the credential vault
          String slotName   = getSharedSlotId(request);
          if(slotName == null)
              slotName=createSlot(request);
          System.out.println("slotName="+slotName);
          String userID   = request.getParameter(CV_USERID);
          String password = request.getParameter(CV_PASSWORD);
        // save only if both parameters are set
        if(slotName != null && userID!=null && password!=null && !userID.trim().equals("") && !password.trim().equals("")) {
             vaultService.setCredentialSecretUserPassword(slotName, userID,password.toCharArray(),request);
           
        }
        }
    if(request.getParameter(DELETE_PRIVATE_CV_ACTION) != null )
    {
        deleteSlot(request);
    }
    response.setPortletMode(PortletMode.VIEW);
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    }

private String createSlot(ActionRequest request) throws Exception
{
    String resourceName = sharedSlotResourceName; //For shared slot resource name should be slot name
    ObjectID segmentID = vaultService.getDefaultUserCredentialSegmentId();
    HashMap<String, String> descriptionsMap = new HashMap<String, String>();
    HashMap<String, String> keywordsMap = new HashMap<String, String>();
    int secretType = CredentialVaultService.SECRET_TYPE_USERID_STRING_PASSWORD_STRING;
    boolean bActive = true; //Active
    boolean bPrivate = true; //
Portlet Private Slot
    CredentialSlotConfig slot=null;
    try
    {
    //Creating slot
        slot= vaultService.createCredentialSlot(resourceName, segmentID,descriptionsMap, keywordsMap, secretType, bActive, bPrivate, request);
        System.out.println("New active slot created: " + slot);
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    return slot.getSlotId();
}

private void deleteSlot(ActionRequest request) throws Exception
{
    String resourceName = sharedSlotResourceName; //For shared slot resource name should be slot name
    try
    {
        String slot=getSharedSlotId(request);
        vaultService.deleteCredentialSlot(slot);
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}
private String getSharedSlotId(PortletRequest request)
{
    String slotId=null;
    try
    {
        for(Iterator it = vaultService.getAccessibleSlots(request); it.hasNext();)
        {
            CredentialSlotConfig config = (CredentialSlotConfig)it.next();
            if(config.getResourceName().startsWith(sharedSlotResourceName))
            {
                slotId = config.getSlotId();
                return slotId;
            }
        }

    }
    catch(CredentialVaultException e)
    {
        System.out.println("Exception while retrieveing slot id " + e);
    }
    return slotId;
}

private Map buildCredentialConfigurationMap()
{
    Map credentialDataMap = new HashMap();
    LinkedList list = new LinkedList();
    list.add("action=j_security_check");
    credentialDataMap.put(HttpFormBasedAuthCredential.KEY_FORM_DATA, list);
    credentialDataMap.put(HttpFormBasedAuthCredential.KEY_USE_AUTH_COOKIES, Boolean.TRUE);
    credentialDataMap.put(HttpFormBasedAuthCredential.KEY_LOGIN_URL, "http://localhost:10039/Login/j_security_check");
    credentialDataMap.put(HttpFormBasedAuthCredential.KEY_LOGOUT_URL, "http://localhost:10039/Login/j_security_check");
    credentialDataMap.put(HttpFormBasedAuthCredential.KEY_PASSWORD_ATTRIBUTE_NAME, "j_password");
    credentialDataMap.put(HttpFormBasedAuthCredential.KEY_USERID_ATTRIBUTE_NAME, "j_username");
    return credentialDataMap;
}
}

Click here to download the source code




2 comments:

  1. thanks Mr Dillibabu very useful

    ReplyDelete
  2. Hi the role specified in the application is not available in WAS

    ReplyDelete