In this Example,we are going to do SSO with a plain J2EE Applications from Portal using CredentialVaultService.
Develop Plain J2EE Application:
Vault Slots
Credential objects
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.
Develop Plain J2EE Application:
- Install the login.war into WAS server.
- Login to http://localhost:10039/Login/TestServlet
- It yields to the following screen
- After entering the credentials
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;
}
}
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
thanks Mr Dillibabu very useful
ReplyDeleteHi the role specified in the application is not available in WAS
ReplyDelete