IBM Portal User Management Architecture (PUMA) SPI

Recently I had a chance to dig into IBM Portal User Management Architecture (PUMA) Service and its SPI (Service Provider Interface). It is used to access (find, create, modify and delete) the information about WebSphere Portal users and groups. If your portal is configured to use LDAP, PUMA will automatically connect to your LDAP.

Although the PUMA interfaces are fairly well defined, but I did struggle through few things I was trying to accomplish. Therefore I decide to share the bits of code with everyone.

To use PUMA SPI you need to familiarise yourself with the following 7 interfaces located in wp.user.api.jar

    The User and Group interfaces returned by the SPI inherit the getObjectID() method from the interface of the Model SPI.
  3. The following provider objects are used to access the User and Group objects

    PumaProfile provides methods that provide read only access to Portal User and Group attributes and identifiers. It also provides a method “public User getCurrentUser() throws PumaException” to get details of current logged in user.
    PumaController provides method to create, modify and delete User and Group profiles.
    PumaLocator provides methods for looking up User and Group objects. The interface can be used to obtain a List of Group objects for all of the groups in which the current user is a member.
  7. Before the portlet can use these provider objects, it must first retrieve the home interface.

    PumaHome interface gives access to the Proivder objects (PumaProfile, PumaController and PumaLocator)
    Although PagingIterator may not be required for most applications, but provides useful pagination features while retreiving Users/Groups with PumaLocator.

Here is a utility IBMPumaUtility class that I created to show the usage of above interfaces. Click here to download

The code above was successfully tested on WPS 7. I hope this helps and if you require more information do send a message. Cheers!

  • Jon

    My portal is integrated with LDAP thoguth Sun Access Manager. I tried to get the User object from PUmaprofile but it returns null. This same code works if I dont go through Sun AM. Any idea why that would be or any solution.


  • Manish

    Hi Jon,

    This is quite surprising that User object is returned null when going through Sun Access Manager. I haven’t encountered this error because I am not using Sun AM.

    I would like to see the code to find out in what context you are calling pumaProfile.getCurrentUser(). Although I don’t think this will be a coding issue because the same is working without Sun AM. Mail me at


    • prakash

      hi manish i having dis error :Exception Occuredjava.lang.ClassCastException: incompatible with whenever using ur code…

  • Sunil

    When I try to find a user thorugh uid attribyte in findUsersByAttribute method, it retruns empty userlist.


    Name myjndiname = new CompositeName(PumaHome.JNDI_NAME);
    PumaHome myHome = (PumaHome) ctx.lookup(myjndiname);
    PumaController pController = myHome.getController();
    PumaLocator pLocator = myHome.getLocator();
    List allusers = pLocator.findUsersByAttribute(“uid”, “sometestuser”);

    It returns empty list. Though the userid thats used in query exists in user registry.
    Am I missing any additional configuration?

    1 thing I would like to point here is.
    In portal puma service spi, we no where bind a user to lookup/edit the user registry. So what user is used by puma portal service spi. Does it use annonymous user?

  • Manish

    Hi Sunil,

    I copied your code snippet into my portlet and it seemed to work without any issues. I emailed you the code and hopefully that works for you.

    We do not explicitly bind the user to call PUMA Service, but current user context is used to decide the service access.

    Let me know how you go or if possible provide some more details about your environment? You can email me on


  • abhishek pdiwa

    hey I have faced the issue regarding accessing PUMA Profile after using the loginService but I am getting the user as null. I dont know why but just want to ask whether any configuration is needed as such for enabling PUMA in loginPortlet???????

    Code snippet-
    I have faced a simple issue regarding using PumaProfile.getCurrentUser() method. I am getting the user as null in it after the LoginService of the portal is called successfully.

    public void processAction(ActionRequest request, ActionResponse response) throws PortletException, {
    LoginService loginService = (LoginService) loginHome.getLoginService(request, response);
    String userId = request.getParameter(FORM_ID);
    String password = request.getParameter(FORM_PASSWORD);

    Map contextMap = new HashMap();
    contextMap.put(LoginService.DO_RESUME_SESSION_KEY, new Boolean(false));
    try {
    loginService.login(userId, password.toCharArray(), contextMap, null);
    } catch (Exception ex) {
    System.out.println(“this login failed with = ” + ex.getMessage());

    javax.naming.Context ctx = new javax.naming.InitialContext();
    PortletServiceHome psh1 = (PortletServiceHome) ctx.lookup(“portletservice/”); service = ( psh1.getPortletService(;

    PumaProfile pp = service.getProfile(request);

    PumaLocator pl = service.getLocator(request);
    PumaController pController = service.getController(request);

    User singleUser = pp.getCurrentUser();

    //The single user is getting null in sysout logs
    System.out.println(“Abhishek—->The Current Login user is: ” +singleUser);
    catch(Exception e){

    I have a simple logic for logging into the portal application by using Loginservice. There is no issue in LoginService. I have implemented this logic in the processAction() of LoginPortlet. After using login service I have initialized the PUMA controller,profile and locator. Now when I use PumaProfile.getCurrentUser() I am getting the user as null.

    I want to know why is getting null?????????? Have I missed something essential?

    Kindly please help me out in this issue.

    Looking forward for your quick response

  • Manish

    Hi Abhishek,

    Once you call the loginService.login( ) method, portal has to redirect to the authenticated area/page and then you can use PUMA API to access current user details.

    Therefore you will have to move out PumaProfile.getCurrentUser( ) code from processAction( ) and place it in the page it redirects to. Perhaps the doView( ) method of the portlet it opens next? You could use IBMPumaUtility.getInstance( ).getCurrentUser( ).

    This is how I understand and usually implement the code. I know it sucks, but if there is a workaround, I would love to know.


  • abhishek pdiwa

    hey thanks manish for your information………..I have tried that thing in portal default.jsp and it is getting the user by using pp.getCurrentUser()……but my application wants the user in the processAction so that i can modify the custom attribute in it which i have added in the attribute list……….I hope you got my point …… there any other way of doing it?

  • abhishek pdiwa

    Hey hi manish,

    I have just made another small change to it………I have added portal filters to it and now after pro-processing I have added the PUMA logic which I had used earlier in processAction()…………Still I am not getting the user and it is showing as null.

    public void doFilter(
    ActionRequest request,
    ActionResponse response,
    FilterChain chain) throws IOException, PortletException {

    System.out.println(“==========Abhishek——>before preprocessing in ACTIONFILTER=============”);
    chain.doFilter(request, response);
    System.out.println(“==========Abhishek——>after preprocessing in ACTIONFILTER==============”);

    PumaProfile pp = service.getProfile(request);

    PumaLocator pl = service.getLocator(request);
    PumaController pController = service.getController(request);

    User singleUser = pp.getCurrentUser();

    //The single user is getting null in sysout logs
    System.out.println(“Abhishek—->The Current Login user is: ” +singleUser);

    .Actually I want to set a user-defined attribute in PUMAController which depends mainly on the type of the user………and after successfully setting it I have to retrieve the same in Portal default.jsp and display to users only certain pages according to the logic written in the user-defined attribute………..

    • Manish

      Hi Abhishek,

      Now I understand the reason why you need to access PUMA API in the processAction( ).

      If you are trying to use PUMA API to retrieve current user immediately after call to LoginService.login( ) you will have to do it differently. Since the page is not redirected, valid session is not bound to the user request.

      What you could do is get user object by calling pumaLocator.findUserByIdentifier( userID ) or pl.findUsersByAttribute(“uid”, userID). Since you have the user id, this should not be an issue.

      A point to note here is that you will have to give Editor access to “Anonymous Portal User” to be able to make calls to PUMA API, otherwise it will return null.


  • abhishek pidwa

    Thanks manish ……..actually I have tried this earlier but I was not sure about the Editor access to Anonymous portal user ………..will update you once it is done

  • abhishek

    Hi manish,

    In reply to your last reply u said that give Editor Access to ‘Anonymous Portal User’. I am confused as to which portlet I should give Editor access. Can u please briefly tell me about that because still I am getting the user as null.

    I have tried the following—->
    1)Resource Persmissions- Users-Editor-Anonymous
    3)Users and Group Permissions-Users-Editor-Anonymous Portal user

    Apart from these some random lookouts but still getting user as null.
    kindly help me in this issue

    • Yogesh

      Hi Manish/Abhishek,

      I am facing the exact issue as above, is there a workaround to get User details using PUMA API immediately after the login() in processAction.
      Working on Portal 8.

      Appreciate the help!


  • Ed

    I am trying to access user attributes through PUMA SPI through portal jndi lookup in the theme of the “myportal” area of the site, but always getting back uid attribute with value “anonymous portal user”. If I use portlet home using portlet jndi home lookup, I can get current user. I see that there are some fix packs for portal 7 for similar issue but I am on so it should be fixed. Any reason why I should not be able to get current user once authenticated and within site?

    utility class:
    public static IUserUtil getInstance() throws NamingException {
    if (pumaUtility == null) {
    pumaUtility = new PortalUserUtil();

    if (pumaUtility.getPumaHome() == null) {
    try {
    Context context = new InitialContext();
    pumaUtility.setPumaHome((PumaHome) context.lookup(PumaHome.JNDI_NAME));
    } catch (NamingException e) {
    log.error(“Caught exception looking up PumaHome using JNDI Name: ”
    + PumaHome.JNDI_NAME + ” exception: ” + e.getMessage(), e);
    throw new RuntimeException(e);

    return pumaUtility;

    public User getCurrentUser() throws PumaException {
    // To retrieve current User
    PumaProfile profile = getPumaHome().getProfile();
    return profile.getCurrentUser();

    public Map getUserAttributes() {
    Map userAttribMap = null;
    try {
    userAttribMap = getUserAttributes(getCurrentUser());
    } catch {… }
    return userAttribMap;

    public Map getUserAttributes(User user)
    throws PumaAttributeException, PumaSystemException,
    PumaModelException, PumaMissingAccessRightsException {
    PumaProfile profile = getPumaHome().getProfile();
    Map values = profile.getAttributes(user,

    theme JSP Page:
    IUserUtil userUtil = PortalUserUtil.getInstance();
    Map userAttribMap = userUtil.getUserAttributes();

    • Ed

      I figured out my PUMA SPI theme problem. The way I was including my jsp was causing the code to be run in a separate thread that has no context (my clue )

      Here’s what I was doing at the end of my theme jsp:
      <script type="text/javascript" src="”>

      There was no reason for including it this way other than I had been doing it in my other static js file. I changed it to this and things started working:

      • Ed

        Sorry, it got cut off:

        changed from:
        < scr ipt type="text/ javascript" src="”>


  • Ed

    Lets try again:


    lessthan+percent+atsign include file=”./js/asa_dynamic_js.jspf” percent+greaterthan

  • ahamed

    Hai Manish,
    i need that wp.user.api.jar file…will u send that jar file to my mail.pls…

    Ahamed Basha S

  • ahamed

    Hai manish,

    Actually my problem is i need to change the user password in tivoli directory,,But when i am using the i got the error about this (package is not available or create class or package for it) and can not resolved..So please help me what are the packages needed to done this work..and pls tell me the what are the steps to be follow to done this work..

    • Manish class is located in

  • ahamed

    Thank you for your immediate response to my questions about that wp.user.api..

  • ahamed

    i am using websphereportal 6.1

  • ahamed

    websphere portal

  • ahamed

    thank u very much…

  • ahamed

    where do i get from the …pls..

  • ahamed

    Hai Manish…

    Can any one tell me how to resolve this error?

    The type cannot be resolved. It is indirectly referenced from required .class files


    • Manish

      Hi Ahamed,

      The class is part of wp.base.jar. I see you have quite a few issues with your library dependencies. You can use Jarminator to find out the jar file that contains your missing classes.

  • ahamed

    thank u..

  • ahamed

    when i am trying to initiate the portletservice home it shows the following error.. incompatible with
    will u help me …

  • ahamed

    the executed line is :

    javax.naming.Context ctx = new javax.naming.InitialContext();
    portletServiceHome = (PortletServiceHome)ctx.lookup(“portletservice/”);

  • Ankit


    I am using WPS (WebSphere Portal Server) 6.1
    WPS provides its own authentication for any deployed application.
    But I am having a separate authentication application which is used in some other projects also.

    Now if I want to bypass the authentication provided by WPS and want to use my own authentication application in its place then what I have to do for that?

    Will PUMA will be helpful for me or any other configuration I have to do?

  • Oliver

    Thank you for the code, it’s very helpfull.
    But there is something I am wondering: if I use this class in order to get the name of the user group of the user every time he connects to a portlet, would it bee thread safe? I mean if I use the getInstance function of this class to create it, would I have some issues when two people will use the portal at the same time (the second one getting the puma home of the first one)?

  • Santosh

    Hai Manish

    I want to know all groups names using PUMA,By using Which method i will retrieve this thing.

    here i am using the code like

    List s;
    try {
    s = pl.findGroupsByDefaultAttribute(uid);
    Iterator i=s.iterator();
    } catch (PumaSystemException e) {
    // TODO Auto-generated catch block
    } catch (PumaMissingAccessRightsException e) {
    // TODO Auto-generated catch block

    But it does give the answer

    please help me out from this

  • Aditya

    Hi Manish,

    I am having problem in accessing an attribute in LDAP. I am able to manipulate that attribute in LDAP browser (JExplorer), however when i write a mathod in jsp, I get AttributeNotDefinedException Exception.

    The code goes as below.
    List digiPassVar = new ArrayList();
    HashMap digiPassVarMap = (HashMap) pp.getAttributes(user,digiPassVar);

    user – User Principal Object
    pp – Object of PumaProfile

    It gives me error as :-
    /* EJPSG0007E: One of the attribute specified is not defined for this member type.digiPass:

    The code works perfect for other attributes, i am able to fetch other. I have tried to map the value in ‘wimconfig.xml’ as,


    but still it doesn’t work. Please help…

    • Manish

      Hi Aditya,

      It should work fine from the code you have provided. I don’t think the problem is in your JSP code.

      Since LDAP shows the “digiPass” property, I guess the problem will be in your portal server settings to read these custom ldap properties. Since I can’t see the whole system. I recommend checking your file.


  • Nitin

    I have used above code in portlet , but I am exception java.lang.ClassCastException: incompatible with

    we are using websphere portal 7
    Can you please let me know how to resovle

    • prakash

      nitin u got solution for dis… help me out what u did for dis error

      • Nitin


        i have placed user related jar in portlet lib directory which was causing issue, after removing jars form lib folder, its resolved.

        • prakash

          well said.. nitin.. i also did same pblm.. after removing .jar from lib folder its working.. thanks a lot

        • prakash

          hi, nitin i want to access values of custom attributes from LDAP server using puma api.. its possible ..if it is help me out..

  • Dilip

    Hello Manish,

    i need to use findUsersByQuery method of PumaLocator, can you please explain (or) share the infomation about how to construct queries using Xpath

  • Santosh

    Hi Manish,

    I want to if check user exists in a group or not can you help me how to check by using PUMA ?

  • Rahul

    Hi Manish,
    I am trying to search users in specific user group. using : groupMembership=’*cn=app-XYZ,ou=Groups,o=XXX*’ but i am getting following error:

    body { margin: 0 0 0 0; padding:0 0 0 0 }
    td,div { font-family:Segoe UI;font-size:9pt;vertical-align:top }
    /* Copyright IBM Corp. 2011 All Rights Reserved. */
    body { margin: 0 0 0 0; padding:0 0 0 0; overflow:hidden; }
    .transcript { background-color:#d2d2d2; }
    .messageBlock { padding-left:10px; padding-right:10px; margin-bottom:3px }
    .message { padding-left:20px; margin-left:95px; word-wrap:break-word; white-space:-moz-pre-wrap; _white-space:pre; white-space:pre-wrap;}
    .messageCont { padding-left:20px; margin-left:95px; word-wrap:break-word; white-space:-moz-pre-wrap; _white-space:pre;white-space:pre-wrap;}
    .other { font-size:11px;color:#39577a;vertical-align:top;font-weight:bold;font-style:normal;float:left; width:95px; }
    .myself { font-size:11px;color:#da8103;font-style:normal;font-weight:bold;font-style:normal;float:left; width:95px; }
    .otherCont { font-size:8px;text-align:right; color:#39577a;font-family:Arial,Lucida Grande;font-style:normal;vertical-align:top;font-weight:bold;float:left; width:95px; }
    .myselfCont { font-size:8px;text-align:right; color:#da8103;font-family:Arial,Lucida Grande;font-style:normal;vertical-align:top;font-weight:bold;float:left; width:95px; }
    .system { font-size:11px; word-wrap:break-word;color:#da8103;font-style:normal;font-weight:normal; white-space:-moz-pre-wrap; _white-space:pre;white-space:pre-wrap; }
    .showTimestamp { padding-left:20px; font-size:11px; float:right; color:#999999;font-style:normal;font-weight:normal; }
    .other1 { font-size:11px; color:#ac2000;vertical-align:top;font-weight:bold;font-style:normal;float:left; width:95px; }
    .otherCont1 { font-size:8px;text-align:right; color:#ac2000;font-family:Arial,Lucida Grande;font-style:normal;vertical-align:top;font-weight:bold;float:left; width:95px; }
    .other2 { font-size:11px; color:#3c9fa8;vertical-align:top;font-weight:bold;font-style:normal;float:left; width:95px; }
    .otherCont2 { font-size:8px;text-align:right; color:#3c9fa8;font-family:Arial,Lucida Grande;font-style:normal;vertical-align:top;font-weight:bold;float:left; width:95px; }
    .other3 { font-size:11px; color:#e25614;vertical-align:top;font-weight:bold;font-style:normal;float:left; width:95px; }
    .otherCont3 { font-size:8px;text-align:right; color:#e25614;font-family:Arial,Lucida Grande;font-style:normal;vertical-align:top;font-weight:bold;float:left; width:95px; }
    .other4 { font-size:11px; color:#0b6ac8;vertical-align:top;font-weight:bold;font-style:normal;float:left; width:95px; }
    .otherCont4 { font-size:8px;text-align:right; color:#0b6ac8;font-family:Arial,Lucida Grande;font-style:normal;vertical-align:top;font-weight:bold;float:left; width:95px; }
    .other5 { font-size:11px; color:#b23290;vertical-align:top;font-weight:bold;font-style:normal;float:left; width:95px; }
    .otherCont5 { font-size:8px;text-align:right; color:#b23290;font-family:Arial,Lucida Grande;font-style:normal;vertical-align:top;font-weight:bold;float:left; width:95px; }
    .other6 { font-size:11px; color:#02e7c7;vertical-align:top;font-weight:bold;font-style:normal;float:left; width:95px; }
    .otherCont6 { font-size:8px;text-align:right; color:#02e7c7;font-family:Arial,Lucida Grande;font-style:normal;vertical-align:top;font-weight:bold;float:left; width:95px; }
    .other7 { font-size:11px; color:#5b3284;vertical-align:top;font-weight:bold;font-style:normal;float:left; width:95px; }
    .otherCont7 { font-size:8px;text-align:right; color:#5b3284;font-family:Arial,Lucida Grande;font-style:normal;vertical-align:top;font-weight:bold;float:left; width:95px; }
    .highlight { background-color:#bed6f8; }
    .datestamp { padding-right:0px; font-size:11px; cursor:default; margin-bottom:1px; background-color:#c0c0c0; width:100%; float:left; text-align:right; color:#ffffff; font-weight:bold; font-style:italic; }
    #chatAlert { float:left; border-bottom:1px solid #E8D091; padding:6px; width:100%; color:#A5754C; }
    #chatAlertImage { float:left; }
    #chatAlertText { float:left; margin-left:6px; margin-right:10px;}
    #chatAlertClose { float:right; margin-right:10px; padding-right:6px; margin-top:0px; }
    #chatAlertText a { color:#A5754C; }
    #chatAlertText a:hover { color:#A5754C; text-decoration:none; }

    .tsDisplay { display:block }.dsDisplay { display:block } EJPSG0015E: Data Backend Problem CWWIM1029E The search expression ‘@xsi:type=’PersonAccount’ and groupMembership=’*cn=XYZ,ou=Groups,o=XXX*” is not valid.

    Could you please suggest some solution to this problem.

    Thank You,

    • prakash

      what snippet code you are using????

  • Jyotsna

    Hi Manish,
    We are using LDAP registry and we are getting some exception while creating users. does puma API works fine with LDAP Registry?