Federated Portals Guide

     Previous  Next    Open TOC in new window    View as PDF - New Window  Get Adobe Reader - New Window
Content starts here

Federating User Profiles

WebLogic Portal enables user profile information to be passed from consumers to producers. This feature allows many of the Personalization features available in WebLogic Portal to function in a federated portal. This chapter explains how to work with user profile information in a federated portal. Before a federated portal can use user profile information, some configuration is required in both the consumer and producer applications.

This chapter includes the following topics:

 


Introduction

This section summarizes the purpose of user profile propagation and how WebLogic Portal propagates user profile data in a federated environment.

What are User Profiles?

A user profile is a collection of property sets that contain user-specific information. WebLogic Portal provides many features that rely on user profiles. For example, the WebLogic Portal Personalization features rely on user profiles to deliver customized content to specific types of users.

For example, you could create a property set in Workshop for WebLogic called human resources that contains properties such as gender, hire date, and email address. This information can be used to personalize the user’s experience in your portal. When users log into a portal, the portal can access the property values and target them with personalized content, e-mails, pre-populated forms, and discounts based on the Personalization rules you set up.

See the Interaction Guide for more information on personalization. For detailed information on creating user profiles, see User Management Guide.

User Profiles in Federated Portals

For a WebLogic Portal producer to return personalized content to a consumer, user information must be conveyed from the consumer to the producer. The basic requirements for using user profile information in a federated portal include:

Tip: Once retrieved, the list of the properties required for a specific portlet is stored in the consumer database for future access.

As shown in Figure 11-1, after a consumer first contacts a producer, the producer responds with a list of the portlets it offers and with a request for the user information that each portlet requires.

Figure 11-1 Producer Requests User Information from Consumer

Producer Requests User Information from Consumer

If a portlet requires user information, the consumer will attempt to supply that information as part of the getMarkupRequest() to the producer before the portlet can be rendered, as illustrated in Figure 11-2. WebLogic Portal uses the P13N API, typically in conjunction with a mapping file, to retrieve the requested user properties on the consumer.

Figure 11-2 Producer Returns Personalized Content

Producer Returns Personalized Content

Platform for Privacy Preferences (P3P)

The WSRP protocol specifies a standard format for storing and exchanging user information. This format, called Platform for Privacy Preferences (P3P), is an internet standard. You can configure WebLogic Portal applications to accept user information presented in this format as well as in the WebLogic Portal user profile format.

See P3P Examples for more information. The P3P specification is available on the W3C website, www.w3.org/TR/P3P.

 


When to Use this Feature

Use this feature if the user properties defined on the producer and consumer do not match. When exactly the same user properties exist on the consumer and producer, you do not need to use this feature.

Tip: In a production environment, the best practice is to specify a property set and property name for each user property you want to propagate. Retrieving all properties is inefficient when only a small subset of properties is needed.

 


Configuring the Producer

To use user profile information in a federated portal, you need to declare on the producer which user properties are required by the portlets deployed on the producer. The declared properties are marshalled in a response to the consumer and returned to the consumer application, which must then return the requested user property values when registering the producer.

The procedures for configuring portlets deployed in a producer to use user profile information differs depending on whether you are configuring Java portlets or non-Java portlets.

This section includes the following topics:

Configuring Java Portlets

The Java Portlet Specification specifies how Java portlets access user attributes such as the name, email address, phone number, and other attributes of the user. This section explains how to specify user attributes for Java portlets deployed in a producer application, and how Java portlets retrieve user information.

Tip: For detailed information on how user information is accessed by Java portlets, refer to the User Information section of the Java Portlet Specification.

Configuring the Deployment Descriptor (portlet.xml)

The Java Portlet Specification defines the <user-attribute> element for specifying user attributes required by a deployed Java portlet. Figure 11-1 shows an excerpt of a portlet.xml file with user properties specified. The <name> elements specify user attribute names.

Listing 11-1 Specifying User Properties in portlet.xml File
<portlet-app>
...
<user-attribute>
        <name>Employee/Language</name>
    </user-attribute>
<user-attribute>
        <name>Employee/Role</name>
    </user-attribute>
...
</portlet-app>

See also Creating Default User Property Sets.

Retrieving User Information in a Java Portlet

The Java Portlet Specification also specifies how Java portlets retrieve user information from the portal environment in which they are deployed. The portlet can retrieve a Map object that contains the user attributes of the user who initiated the request. You can retrieve this Map object from the request using the PortletRequest.USER_INFO constant.

The example code in Listing 11-2 shows how a Map of user information is retrieved from the request in a JSP associated with a Java portlet. User property values are retrieved from the Map using the user property names as keys.

Listing 11-2 Retrieving User Information in a Java Portlet
...
    
    Map<String, Object> props;
PortletRequest portletRequest = (PortletRequest)
    request.getAttribute("javax.portlet.request");
if (portletRequest != null) {
props = (Map<String, Object>)
       portletRequest.getAttribute(PortletRequest.USER_INFO) ;
} else {
props = null ;
}

if (props == null) {%>
<p>Empty Profile</p>
<%} else {%>
<p><%= props.get("Employee/Language") %></p>
<p><%= props.get("Employee/Role") %></p>
<%}%>
...

Creating Default User Property Sets

Listing 11-3 shows a sample user attribute specified in a portlet.xml file. This section explains how you can streamline the <user-attribute> property by creating default user property sets. For example, by creating a default user property called “Employee,” the name attribute in Listing 11-3 could be shortened to <name>Language</name>.

Listing 11-3 User Attribute Specified in portlet.xml

<user-attribute>
    <name>Employee/Language</name>
</user-attribute>

To create a default user property set, first create a weblogic-portlet.xml file in the WEB-INF directory of your portal web application. You can then use the <user-property-set> attribute to configure default user property sets.

Listing 11-4 shows how to create a default user property set called “Employee” for all portlets in the web application:

Listing 11-4 Default Property Set Applied to All Portlets
<portal-container>
<user-property-set>Employee</user-property-set>
</portal-container>

Listing 11-5 shows how to create a default user property set for a specific portlet:

Listing 11-5 Default Property Set Applied to Specific Portlets
<portlet>
<name>portletName</name>
<user-property-set>Employee</user-property-set>
....
</portlet>

With the default user property set “Employee” specified in weblogic-portlet.xml, you can then code the <user-attribute> value shown Listing 11-3 as follows in the portlet.xml file.

Listing 11-6 User Attribute

    <user-attribute>
        <name>Language</name>
    </user-attribute>

For more information on the weblogic-portlet.xml file, see “Building Portlets” in the Portlet Development Guide.

Mapping User Properties

If the user properties on the consumer and producer do not match, you can create a mapping file on the consumer. A mapping file allows the consumer to retrieve user properties that map to the properties requested by the producer. For detailed information on mapping user properties, see Configuring the Consumer.

Configuring Non-Java Portlets

This section explains how to specify user attributes for non-Java portlets deployed in a producer application.

Configuring the Deployment Descriptor File

For non-Java portlets, you specify required user properties in the descriptor file wsrp-producer-config.xml. This file is located in the WEB-INF directory of your producer web application. Listing 11-7 shows a sample wsrp-producer-config.xml file. The <requiredUserProperties> element specifies the required user properties for portlets deployed in the producer web application (shown in bold type). In the example, the value All specifies that consumer must supply all available user profile information to the producer. Other possible values are discussed in this section.

Listing 11-7 Sample wsrp-producer-config.xml File
<?xml version="1.0" encoding="UTF-8"?>
<wsrp-producer-config
xmlns="http://www.bea.com/servers/weblogic/wsrp-producer-config/9.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:uddi="urn:uddi-org:api_v2"
xsi:schemaLocation="http://www.bea.com/servers/weblogic/wsrp-producer-config/9.0 wsrp-producer-config.xsd">
<description></description>
<service-config>
<registration required="true" secure="false"/>
<service-description secure="false" supports-method-get="true"/>
<markup secure="false" rewrite-urls="true" transport="string"/>
<portlet-management required="true" secure="false"/>
</service-config>
<supported-locales>
<locale>en</locale>
<locale>en-US</locale>
</supported-locales>
<requiredUserProperties properties="All">
    </requiredUserProperties>
</wsrp-producer-config>

The <requiredUserProperties> element contains one attribute, called properties, which takes one of these three values:

The value given for the name property can take one of these forms:

If no user information is specified in wsrp-producer-config.xml, the behavior is the same as if a value of None were specified in <requiredUserProperties>.

Retrieving User Information in a Portlet

The code excerpt in Listing 11-8 shows how user properties are retrieved in a portlet’s JSP file using the P13N tag <profile:getProperty>.

Listing 11-8 Retrieving Values in a Portlet
...
<%
if (request.getUserPrincipal() != null) {
%>
<profile:getProfile profileKey="<%= request.getUserPrincipal().getName() %>"      />
<%
} else { %>
<profile:getProfile profileKey="anonymous" groupOnly="true" />
<%
}
%>

  <tr>
<td>Name</td>
<td id="wsrp_date"><profile:getProperty propertySet=
"Employee" propertyName="name"/></td>
  </tr>
  <tr>
    <td>Gender</td>
    <td id="wsrp_int_code"><profile:getProperty propertySet=
    "Employee" propertyName="gender"/></td>
    </tr>
  <tr>
...

Handling User Property Extensions

If a WebLogic Portal or non-WebLogic Portal consumer sends extended P3P user profile information, the portlet can retrieve the extensions as a List object obtained from the <profile:getProperty> tag. Listing 11-9 shows example code that extracts a List containing telephone extensions. In this case, the property homeInfo/postal/extensions is an extended WSRP user property.

Listing 11-9 Retrieving User Profile Extensions
<profile:getProperty propertySet="<%= UserProperty.P3P_PROPERTY_SET_NAME %>" propertyName="homeInfo/postal/extensions" id="postalExtsObj"/>
<%
List<Element> teleExts = (List<Element>) postalExtsObj;
if (teleExts != null) {
for (int i = 0 ; i < teleExts.size() ; i++) {
                   String extStr = teleExts.get(i)

%>
                   <tr> <td>Postal Extension[<%= i %>]</td>
                   <td colspan="2"
                   id="postal_extensions[<%=i%>]"><%= extStr %></td> </tr>
<%  }
  }%>

Mapping User Information on the Consumer

Consumers may map the user properties requested by producers to properties that exist on the consumer. For detailed information on mapping user properties, see Configuring the Consumer.

 


Configuring the Consumer

In many cases, the user property set and property names that exist on a producer do not match those on the consumer. Therefore, WebLogic Portal allows you to map these names appropriately. This section explains how to map property set and property names using a configuration file or programatically with a mapping class.

This section includes these topics:

Using a Mapping File

Specify user profile mappings in the wsrp-user-property-config.xml file. This file is located in the WEB-INF directory of the consumer web application.

As shown in Listing 11-10, the element <wsrp-user-property-map-bean> is the top-level element that can appear in this configuration file. The elements that can fall under <wsrp-user-property-map-bean> are shown in bold type and include:

As shown in Listing 11-10, the <producer-user-property-map> element can be used to create producer-specific mappings directly or with a mapping class.

Listing 11-10 Example wsrp-user-property-config.xml File
<?xml version="1.0" encoding="UTF-8"?>
<wsrp-user-property-map-bean xmlns="http://www.bea.com/ns/portal/90/wsrp-user-property-config">

    <!-- Maps ldap/name -> Employee/name for all registered producers -->
    <user-property-map>
<producer-property-name>Employee/name</producer-property-name>
<consumer-property>ldap/name</consumer-property>
</user-property-map>

    <!-- Specifies a mapper class to apply to all registered producers -->
    <mapper-class-name>myClasses.MyUserPropertyMapper1</mapper-class-name>

    <!-- User Property Map for specific producer -->
    <producer-user-property-map>
<producer-handle>complexProducer</producer-handle>
<user-property-map>
<producer-property-name>Employee/number</producer-property-name>
<consumer-property>"xxxxxx"</consumer-property>
</user-property-map>
</producer-user-property-map>

    <!-- Specifies a mapper class for specific producer -->
    <producer-user-property-map>
<producer-handle>complexProducer2</producer-handle>
<mapper-class-name>myClasses.MyUserPropertyMapper2</mapper-class-name>
</producer-user-property-map>
</wsrp-user-property-map-bean>

The <producer-property-name> sub-element of <user-property-map> specifies the propertySet/propertyName pair of the requested producer property, and the <consumer-property> sub-element specifies the equivalent pair that exists on the consumer.

The <producer-property-name> and <consumer-property> pairs can take the following forms:

Using a Mapping Class

In addition to using a mapping file to map requested producer properties to consumer properties, you can create a mapping class to programmatically map and set user property values on the consumer. To use a mapping class, you need to do the following:

Writing the Mapping Class

To create a mapping class:

  1. Extend the com.bea.wsrp.consumer.userproperty.DefaultUserPropertyMapper class.
  2. Override the getProducerProperties method to implement the mapping functions that you want to create. For detailed information on this method, refer to the Javadoc. The mapper class example in Listing 11-11 sets the gender property for a user based on the user’s name.
  3. Note: Extending DefaultUserPropertyMapper and overriding getProducerProperties is the simplest and best practice, although it is not required. You can also extend its abstract base class if you want to.
  4. Configure the mapper class in the wsrp-user-property-config.xml file. To do this, add lines to wsrp-user-property-config.xml that follow the pattern shown in Listing 11-11, where producerHandle is the unique name that identifies the producer on the consumer, and myClasses.MyMapperClass is the full classname of the mapper class.
  5. Listing 11-11 Example Mapper Class
    package com.bea.portlet.qa.wsrp.userprops;

    import java.util.Arrays;
    import java.util.Collection;
    import java.util.HashSet;
    import java.util.Map;
    import java.util.Set;

    import com.bea.p13n.property.EntityPropertyCache;
    import com.bea.wsrp.consumer.userproperty.DefaultUserPropertyMapper;
    import com.bea.wsrp.consumer.userproperty.RequiredUserProperties;
    import com.bea.wsrp.consumer.userproperty.UserProperty;

    public class TestUserPropertyMapper extends DefaultUserPropertyMapper {
    private final static Set<String> MALE_NAMES = new HashSet<String>() ;
    private final static Set<String> FEMALE_NAMES = new HashSet<String>() ;

    static {
    final String[] maleNames = {"Nate","Nathan","Eric","Subbu","Scott"};
    MALE_NAMES.addAll(Arrays.asList(maleNames)) ;
    final String[] femaleNames = {"Mandy","Geeta","Jenn","Jen","Jenny"} ;
    FEMALE_NAMES.addAll(Arrays.asList(maleNames)) ;
    }

    /**
    * Map set the user's gender if user.name.given is set
    * @param requiredProperties the properties requested by the producer
    * @param map A map where the key is the producer's name and
    * the value is the consumer's name
    * @param profile the User's profile on the consumer
    * @return the properties mapped to the producer
    */
    public Collection<UserProperty> getProducerProperties(
    RequiredUserProperties requiredProperties,
    Map<String, String> map,
    EntityPropertyCache profile) {

    final Collection<UserProperty> properties =
    super.getProducerProperties(requiredProperties, map, profile) ;
    if (requiredProperties.isPropertyRequired("HR", "gender")) {
    final String givenName = (String) getProperty(profile, "HR", "name.given") ;
    if (MALE_NAMES.contains(givenName)) {
    addUserProperty(properties, "HR", "gender", "M") ;
    } else if (FEMALE_NAMES.contains(givenName)) {
    addUserProperty(properties, "HR", "gender", "F") ;
    }
    }
    return properties ;
    }
    }

Configuring the Mapping Class

You need to declare mapping classes in the wsrp-user-properties-config.xml file. To do this, use the <mapper-class-name> element. This element takes a fully qualified classname as its property, as shown in the following example:

<mapper-class-name>myClasses.MyMapperClass</mapper-class-name>

You can place this element directly under the <wsrp-user-property-map-bean> element or the <producer-user-property-map> element. For detailed information on the configuration file, see Using a Mapping File.

Mapping Constants

In addition to mapping user properties to user properties, you can map user properties to constant values. You can map to constants in the configuration file or in a mapper class. Listing 11-12 shows part of a wsrp-user-properties-config.xml file where a property called long is mapped to a constant of type long, which is enclosed in /L delimiters.

Listing 11-12
...
        <user-property-map>
<producer-property-name>map/long</producer-property-name>
<consumer-property>/L42/L</consumer-property>
</user-property-map>
...

Table 11-1 includes the full set of constant delimiters.

Table 11-1 Constant Delimiters
Type
Delimiter
Example
String
”Hello World”
Boolean
/B
/Btrue/B
Long
/L
/L42/L
Double
/D
/D3.14159/D
Date
/T
/T1975-09-27T14:38:11-07:00/T

If you create a mapping class, you can specify constants using the delimiters shown in Table 11-1 or use the constants defined in the com.bea.wsrp.consumer.userproperty.UserProperty interface. For details on this interface, refer to the Javadoc.

 


P3P Examples

This section recasts some of the examples given previously in this chapter to show how to use P3P attributes instead of WebLogic Portal user attributes. This section includes the following examples:

This section includes these examples:

Example: portlet.xml file with P3P Attributes

The portlet.xml file is a standard deployment descriptor for Java portlets. Listing 11-13 shows a portlet.xml file that includes P3P attributes. For more information on this file, see Configuring Java Portlets.

P3P attribute names always begin with the prefix user, and by convention, a dot (.) separator is used to separate elements of a name (for example: user.name.given). For a complete set of names used by Java portlets, refer to the Java Portlet Specification.

Listing 11-13 Specifying User Properties in portlet.xml File
<portlet-app>

    <user-attribute>
        <description>User Given Name</description>
        <name>user.name.given</name>
    </user-attribute>
    <user-attribute>
        <description>User Last Name</description>
        <name>user.name.family</name>
    </user-attribute>
    <user-attribute>
        <description>User eMail</description>
        <name>user.home-info.online.email</name>
    </user-attribute>
    <user-attribute>
        <description>Company Organization</description>
        <name>user.business-info.postal.organization</name>
    </user-attribute>
...

</portlet-app>

Example: Retrieving P3P User Information in a Java Portlet

The example code in Listing 11-14 shows how a Map of user information is retrieved from the request in a JSP associated with a Java portlet. Note that standard P3P user property names, such as user.bdate, are used in the file.

Listing 11-14 Retrieving User Information in a Java Portlet
...
Map<String, Object> props;
PortletRequest portletRequest = (PortletRequest)     request.getAttribute("javax.portlet.request");
if (portletRequest != null) {
props = (Map<String, Object>)        portletRequest.getAttribute(PortletRequest.USER_INFO) ;
} else {
props = null ;
}

if (props == null) {%>
<p>Empty Profile</p>
<%} else {%>
<p><%= props.get("user.bdate") %></p>
<p><%= props.get("user.business-info.telecom.telephone.intcode") %></p>
<%}%>
...

Example: Retrieving User Information in Other Portlets

The code excerpt in Listing 11-15 shows how P3P properties are retrieved in a portlet’s JSP file using the P13N tag <profile:getProperty>. WebLogic Portal recognizes the constant com.bea.wsrp.consumer.userproperty.UserProperty.P3P_PROPERTY_SET_NAME to be the set of standard P3P user properties.

Listing 11-15 Retrieving P3P Values in a non-Java Portlet
<%@ page import = "com.bea.wsrp.consumer.userproperty.UserProperty" %>
...
<%
if (request.getUserPrincipal() != null) {
%>
<profile:getProfile profileKey="<%= request.getUserPrincipal().getName() %>"
     />
<%
} else { %>
<profile:getProfile profileKey="anonymous" groupOnly="true" />
<%
}
%>

  <tr>
    <td>Date</td>
    <td id="wsrp_date"><profile:getProperty propertySet=
    "<%= UserProperty.P3P_PROPERTY_SET_NAME %>" propertyName="bdate"/></td>

  </tr>
  <tr>
    <td>Int Code</td>
    <td id="wsrp_int_code"><profile:getProperty propertySet=
    "<%= UserProperty.P3P_PROPERTY_SET_NAME %>" propertyName=
    "businessInfo/telecom/telephone/intcode"/></td>
  </tr>
...

  Back to Top       Previous  Next