Developer Tutorial UME 40
Developer Tutorial UME 40
SAP NetWeaver 04
How To
Developing
User Management
Engine 4.0
Version 1.00 Juni 2004
Applicable Releases:
SAP NetWeaver 04
Summary
EP 6.0 uses the SAP User Management Engine (UME) 4.0 to enable integration of the portal
with a customer's existing LDAP or user management solution. The UME is used by the SAP
Netweaver platform.
The scope of this document is to a Developer Guide for the User Management Engine (UME)
that is provided by the Web Application Java Server for Java applications and Enterprise
Portal Components.
From the application point-of-view, the UME provides three main functions:
1.2
UME user data is stored in one or more repositories. Each type of repository has its own
persistence adapter. The application-programming interface (API) is a layer on top of the
persistence manager. Please refer to the online help for the UME for configuration
information.
1.3
There are several mechanisms available for authenticating users on the SAP NetWeaver
platform. In addition, if you have many systems in your system landscape, then a Single Sign-
On environment is also desirable to reduce the number of passwords that users have to
remember.
The SAP Web Application Server (SAP Web AS ) is the underlying technology for
authenticating users with SAP NetWeaver. See the tables below for an overview of the
mechanisms available for each SAP Web Application Server personality and whether the
mechanism is used directly for user authentication or for Single Sign-On.
Mechanism
User
Authentication
Single
Sign-On
ABAP
Java
x
x
For more information about how these mechanisms work and how to configure them on the
SAP Web AS , see http.//help.sap.com
1.4
Summary
You can use different types of authentication on the SAP Enterprise Portal. This enables you
to choose the required type of security authentication mechanisms for your applications.
The logon stacks enable you to choose different combinations of authentication types for
each application you create, and for each of the components on the server with applied
security restrictions.
2.2
Interface IAuthentication
A prerequisite for any access control and business logic is that a user is logged on. We
provide a simple API to check whether a user is logged in, to enforce that a user is logged in
and to get the logged in user (object):
Example:
With the following lines of code at the beginning of a servlet you can enforce that a user is
logged on:
package com.sap.security.api;
IUser user =
UMFactory.getAuthenticator().forceLoggedInUser(
req,
resp);
if (user == null)
return;
Subsequently, the returned user object can be used for access control and to query the users
profile.
Note:
As forceLoggedInUser() changes the response if the user isn't yet logged on (see next
chapter for details), make sure that you
Thus, you should not use forceLoggedInUser within a servlet, but in the controller servlet (see
for example, struts for details). Then, use getLoggedInUser() within your application.
2.3
Session Handling
If applications use J2EE's session management to store confidential and user relevant
information, we have to make sure that this information is invalidated if the logged on user
changes. J2EE's session management is explicitly local to an application / servlet context.
While we do not plan to develop a global central session management, we still have to
implement the functionality for the logged on user.
From the Servlet Specification: HttpSession objects must be scoped at the application /
servlet context level. The underlying mechanism, such as the cookie used to establish the
session, can be shared between contexts, but the object exposed, and more importantly the
attributes in that object, must not be shared between contexts.
Scenario:
1. User A logs on and accesses some data that is temporarily stored in the session
context of the servlet.
2. User A logs off
3. User B logs on.
4. Now, all information related to user A must be invalidated. (Otherwise, user B might
be able to get access to some of users information
This is realized with the following procedure in getLoggedInUser() /
forceLoggedInUser():
Whenever a new user logs on, we store a reference to the logged on user in the session (if
necessary, a new session is created).
If the session already contains a reference to a different user (this includes the case that the
session contains a user reference but there's currently no user logged on), the session is
invalidated.
On log off, the SSO cookie is removed and the session is invalidated.
Thus, it is essential that the applications use getLoggedInUser() at every request.
Note:
By caching the necessary information to verify whether the logged on user has changed, UM
will optimize the performance of getLoggedInUser().
2.4
Although this is transparent for the applications and might change in the future, here's a brief
description of how authentication and SSO work:
After a user successfully logs on, an encrypted cookie is sent to the user.
In subsequent requests, this cookie can be used for SSO. The method getUser()
verifies that cookie and retrieves the user information, if available.
The same is true for forceLoggedInUser(), if a cookie exists.
If forceLoggedInUser() is called and the user is currently not logged on (for example,
he does not have the cookie), he is redirected to the logon page (or the HTML-code
for the log on page is sent directly). In that step, the current URL (for example, the
URL of the servlet or JSP that has called forceLoggedInUser()) is passed to the logon
page. After a successful logon, the user is automatically redirected back to the current
servlet.
All non Portal Applications access all the functionality of UME through the class
com.sap.security.api.UMFactory.
For EP access via IUser me = request.getUser(); See obtaining a user object below
//Get an 'IUserFactory'-object to instantiate user-objects.
IUserFactory userFactory= UMFactory.getUserFactory();
3.2
Interface IUser
The central point of the Usermanagement is the user object exposed to the application by
implementing one of the following interfaces:
Interface IUser
This interface provides read-access to all available information:
the Company the user belongs to
the profile like name, address
the authorization information (is the user allowed to do something?)
Interface IUserMaint
This interfaces extends the IUser interface and adds the possibility to modify the user
data.
Note
This separation was done for multiple purposes:
Most of the time, the applications only need read access. By using the special readonly interface, we improve the performance of the application significantly.
The design of the Business Service Framework defines the user information as
central information maintained centrally. Thus, changing the data should only occur in
very special situation.
3.3
To get the currently logged on user object, use the IAuthentication interface as described in
the next chapter. To get any user object either based on a unique key or by doing a search,
use the methods available in the IUserFactory.
//get
IUser
//get
IUser
//get
IUser
user by portalrequest
me= request.getUser();
any user
getUser(String uid);
logged on user
user= userFactory.getUserByLogonID(username);
3.4
Service User
A service user is a programmatically created user that is authenticated and whose attributes
contain a valid ticket. Its purpose is basically to impersonate an identity with certain privileges.
Service user don't log on interactively. The ticket that's contained in the attributes is usually
used to log on to a remote portal/SAP System/whatever from within a batch job or whatever
(in situations where no interactive logon has taken place).
For a service user it is possible to define usermapping, assign a role and to assign free
attributes.
3.4.1 ServiceUserFactory
The serviceUserFactory is accessible via the UME API in
UMFactory().getServiceUserFactory()
The ServiceUserFactory provides following methods:
public com.sap.security.api.IUser getServiceUser(
String uniqueName)
throws UMException
In order to get a service user the above message has to be called. The serviceUserFactory
verifies that this user is a service user. Service users are defined as regular users, but have
their own namespace:
private static final String SERVICEUSER_NAMESPACE=
"$serviceUser$";
After verifying the service user this method returns an IUser object with a ticket attached to a
transient attribute. The user
user.setTransientAttribute(
ILoginConstants.SSOTICKET_USER_ATTRIBUTE,
t);
public IUserMaint newServiceUser(String uniqueName)
throws UMException;
public void deleteUser(String uniqueID) throws UMException;
boolean isServiceUser(String uniqueName)
"notificator_service",
"cmadmin_service",
"action_inbox_service"
3.4.3 Authentication of service users
Service users which are returned via the factory only have a ticket attached in the transient
attributes. Since the service users are only contained in the database they
3.4.4 Security of service users
Service users own certain privileges that are needed to perform a special task. E.g. we might
need a special service user that has all necessary permissions to perform every possible task
on an ACL (delete, modify, etc.). Obviously, the API to create service users must be
protected. Therefore, we plan to add a permission check to the create() method of the service
user factory. See the below code sample.
As one can see, the call name acts as target and the user name as action. Using this
granularity, you can specify in a detailed manner which code can instantiate which service
users. Possible privileges could be
codeBase ${portal.home}\WEB-INF\portal\…\private\lib\km.jar {
grant ProtectedCallPermission createServiceUser
IndexService,QueueService;
}
3.5
In EP 5.0 you could simply call getUid() to obtain the logon ID. This method is deprecated
in EP6 due to the fact that a user can be associated with multiple logon accounts.
getUniqueId() as a replacement for getUid(), but this returns a value that must be
parsed to get the logon ID. You can access the actual logon ID by iterating through the
IUserAccounts array obtained by calling getUserAccounts(). The logon ID is retrieved
using the new call getLogonUid(). Often times you can simply pick the first element in the
array:
response.write(
"<br>Number of Login Accounts: " + accounts.length);
for (int i= 0; i < accounts.length; i++) {
response.write(
"<br>** Login ID #"
+ i
+ ": LogonUID="
+ accounts[i].getLogonUid()
+ ", AssignedUID="
+ accounts[i].getAssignedUserID());
response.write(
"<br>Last Login: "
+ accounts[i]
.getLastSuccessfulLogonDate()
.toString());
response.write(
"<br># Logins: "
+ accounts[i].getSuccessfulLogonCounts());
}
}
3.6
EP6 contains a enhanced role structure. The role structure in EP5 was fairly simple and each
role name was unique. In EP6, roles can now be nested in folders which was not possible in
EP5. This new structure facilitates new mechanisms for delegated administration and other
scenarios. As a result, all roles now have a unique identifier which allows the UME to prevent
name clashes (e.g. roles having the same name). Most of the role APIs require the unique
role ID as a handle or key to obtain the role information.
List of roles for a specific user
A list of roles can be obtained by calling getRoles() on the IUser object. This returns an
iterator that allows you to stroll through the roles the user has. The iterator contains the
unique Ids of the roles associated with the user. In order to get the actual information about a
specific role you need to use the Role Factory to obtain an instance of that role. The unique
ID is passed to the role factory's getRole() method.
3.7
There is the possibility to search for users with arbitrary attributes. To do that, you obtain
IUserSearchFilter with the following method:
public IUserSearchFilter getUserSearchFilter() throws UMException
Once the IUserSearchFilter contains all search attributes, you can search the respective
users with:
public ISearchResult searchUsers (IUserSearchFilter filter)
Searching for a role involves a few steps:
1. Build a search filter (IRoleSearchFilter) to look for the role,
2. Execute the search by calling searchRoles() on the Role Factory
3. Iterate through the search result list (ISearchResult)
The following example attempts to obtain a single role. It throws an exception if the role is not
found, or the name is not unique (e.g. search returns more than one role).
10
} catch (UMException e) {
response.write(
"Error getting role: " + e.getLocalizedMessage());
}
if (user.isMemberOfRole(superRole.getUniqueID(), true))
response.write(" IS a super admin");
else
response.write(" IS NOT a super admin");
11
4 User Mapping
4.1
Summary
User mapping is a feature that has been introduced first to SAP products with EP 5.0. It is a
facility to maintain logon data for users for 3 rd party systems. What I call "logon data"; can be
simply user id and password, but also additional data like NT-Domain, language. In EP 5.0,
user mapping is available as both a personalization feature available for every end user and
as an admin feature that allows administrators to map users, groups or roles to specific
accounts. In a productive environment, the user mapping functionality contains a html UI that
allows to maintain the data. In order the portal environment, the UI calls the system landscape
service to get a complete list of all the systems that user mapping should be possible for (thus
every system that user mapping is desired for needs a certain flag in the system landscape).
4.2
For accesing User Mapping data, the UME offers two Interfaces:
IUserMappingService and IUserMappingData.
IUserMappingService is available via ServiceReference= " com.sap.portal.usermapping "
The following Code Sample explains the use of the usermapping API:
import
import
import
import
import
import
import
import
import
12
13
Summary
The portal infrastructure allows many users to perform an operation on a resource, for
example create, modify and delete a portal object. Therefore it is necessary to provide a
security concept, which allows the application to check that the user has the permission to
perform an action. The concept implemented in EP 6.0 is based on an ACL solution (Access
Control List), which allows an administrator (object creator) to create a new ACL object and
assign it to the owner.
5.2
The ACL solution provides an interface, which enables the access to the ACL objects and
allows the application to:
The ACL solution is integrated into the UserManagement Service, which is running on EP 6.0.
The service allows the applications to perform the actions. The collaborative editing of ACL
object is not allowed.
5.3
With the default ACL Manager all Acl's and permissions use a common namespace for all
applications that use Acl's. This can cause some conflicts, if someone doesn't pay full
attention to their object ID's and permission names (i.e. doesn't use a object type prefix).
Therefore, UMFactory provides a method getAclManager(String applicationID) , which
gives you an application specific ACL manager. With this manager you have an own
namespace for your application. So no conflicts can occur with other applications that also
use Acl's.
But this also means, you have no access at all to Acl's and permissions of other applications!
5.4
ACL API
The Application that uses the ACL API works with following interfaces:
5.4.1
com.sap.security.api.acl.IAclManager
This interface defines all the methods that are required for the ACL general administration. It
allows application to:
Create, modify, read and delete an ACL object for a portal object,
Check the permission for a principal on an object,
Add, remove and get available supported permissions,
14
5.4.2 com.sap.security.api.acl.IAcl
This interface allows application to:
5.4.3 com.sap.security.api.acl.IAclEntry
The ACE object stores information about a principal and its permissions. It allows the
application to:
5.4.4 com.sap.security.api.acl.PermissionStatus
The permission status object stores information, if the permission is allowed, denied or
undefined for a given principal. The application gets the ACL Manager from PRT, which
illustrates following example:
IAclService service = (IAclService)
PortalRuntime.getRuntimeResources().getService(IAclService.SERV
ICE_ID);
IAclManager manager =
service.getAclManager();
In UM, the application gets the ACL Manager from the UMFactory with the following example:
IAclManager aclManager =
UMFactory.getAclManager();
5.4.5 com.sap.security.api.acl.IAclHierarchy
This Interface provides the application an access point to:
5.5
Check the permission for a principal on a list of object Ids which represent the parent
objects of the former object,
Propagate an ACE to the members of a object ID tree. If you change the ACE for a
root object, this new ACE will be propagated to all members of the sub tree from this
root. All these entries are inherited.
ACL Manager Interface
15
Note: A point is not allowed in the object type, but in the permission name!
- Optional: You can use global permissions (permissions without object type)
- Permissions must be unique within the namespace of the ACL Manager you are using. This
means if you use an application specific ACL Manager, the permissions have to be unique
within your application. If you use the default ACL Manager, the permission have to be
globally unique.
Object Id's:
-They also have to be unique within the namespace of the ACL Manager you are using (see
above). Therefore they should have a prefix with the service name and/or the object type.
The following code exsample shows some typical functions:
//Get default ACL Manager
IAclMAnager manager = UMFactory.getAclManager();
// Get specific ACL Manager
IAclMAnager manager = UMFactory.getAclManager("Workflow");
16
17
http://www.sap.com/netweaver