|
Foundation |
|
| |||||||||||
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |
See:
Description
Interface Summary | |
---|---|
GlobalProfileInterface | Global profile. |
LogChangeListener | Deprecated. Log changes are now obsolete. |
ProfileInterface | The Profile class maintains information about a user that generally pertains to a specific application. |
UserContextInterface | The UserContextInterface provides a mechanism for maintaining information about a user entity. |
UserIdentityInterface | A user identity is an authenticatable principal and credential within a given domain. |
UserServiceInterface | The UserServiceInterface provides mechanisms for storing information about users and retrieving user information. |
Class Summary | |
---|---|
CredentialPermission | This class is used to protect the retrieval of credential information from the UserIdentity class. |
CredentialPermissionCollection | Collection of credential permissions. |
LoginFailure | |
Profile | The Profile class maintains information about a user that generally pertains to a specific application. |
ProfileDomain | This class is used by the UserServiceInitializer to hold the configuration data about Profiles. |
SimpleUserIdentity | The SimpleUserIdentity class implements a simple user/password identity. |
SubjectAuthenticator | This class is used to marshal the contents of a Subject across a remote link to a UserService in order to create a UserContext based on the contents of the Subject. |
SubjectMatter | This class is used to marshall the contents of a Subject across a remote connection. |
SummaryData | |
SummaryDataEntry | |
UserContext | The UserContext provides handles to the user identities and profile services. |
UserContextPermission | This class is used to protect UserContext objects that are stored in the UserService. |
UserPWChanger | Application used to change a user login credential in a deployed SAS Foundation User Service. |
UserService | The UserServiceInterface provides mechanisms for storing information about users and retrieving user information. |
UserServiceMBean | User Service MBean. |
Exception Summary | |
---|---|
CallbackCancelledException | |
NonPersonAuthenticationException | |
UserInitializationException | This class encapsulates an exception that occurs during UserContext initialization, but may still leave the UserContext in a usable state. |
UserUnknownException |
Maintain user identities and profiles.
The User Service is designed to assist in creating, locating, maintaining, and aggregating information about users of the Foundation Services. A user can be an individual or a group. A user's information is contained in a user context. The context contains the user's active repository connections, identities and profile. Identities are used to authenticate the user with various other services. The profile is actually a collection of global and application profile information that applies to the user.
The User Service is comprised of three major functional areas: User Context sharing, profile management and authentication services.
The User Service itself can store and retrieve UserContext objects for
sharing between applications. To store a UserContext, call the
setUser
method. To retrieve a UserContext, call the getUser
method. The UserContext objects stored in the User Service
are protected by a UserContextPermission. A UserContextPermission
must be granted for an application to retrieve User Contexts. To grant
this permission, add the following to the policy or auth.policy file:
grant { com.sas.services.user.UserContextPermission "username" "read"; }; |
The UserContext has mechanisms for choosing the user's preferred locale. Since the UserContext itself can't interact with a client, the UI is responsible for providing any "hints" like an HTTP request locale using the UserContext.setLocale() method. The locale can then be retrieved via the Usercontext.getLocale() method. It will try to return first a locale from the user profile. This gives the user their preferred locale even if they're using a browser or other client in a different locale (because they're using a different computer, or whatever). Then it will check for the explicitly set locale, and finally fall back to the JVM default locale.
A profile is a collection of name/value pairs that specify preferences, configuration or initialization data for a user for an application. The key is a string. The value can be a string, or a complex object. It's also possible for there to be multiple values for a key.
The simplest profile representation is a collection of name/value pairs where the values are all single-valued strings. If an application uses a profile that can be represented in this way, the generic Profile class can be used to access it.
Profile information is grouped according to application. All the
data that's been configured for a user for a given application
name is contained in one Profile object. The application profiles
can then be nested in a tree structure. Information can be accessed
in various ways. The "global" profile is at the root of the profile
tree. Information in this profile transcends individual applications
and usually contains information about the user (nickname, title,
address, etc). Below this are the application profiles, which may
have subprofiles. For instance, there may be an application profile
named "Solutions", which has subprofiles named "Marketing", "Sales",
and "Purchasing". Once the user context is created, the "Solutions"
profile can be loaded using the loadProfile method of the UserService.
This process should also load the subprofiles of the "Solutions"
application. If this is successful, there are two options for
accessing the information in the profile. To start, get the
global profile from the UserContext with the getProfile
method.
The global profile can then be queried for the desired profile
attribute using the getAttribute
method, passing in
the application string "Solutions/Sales". This will look first in
the "Sales" profile, then in the "Solutions" profile, then in the
global profile for the requested key. When a value is found, it's
returned. This mechanism allows profile values to be set at a
general level, and overridden at more specific levels.
Alternatively, the profile for the application can be retrieved
by calling the getProfile
method from the global
Profile with the application path. For instance get the global
profile using the getProfile
method of the UserContext,
then call the getProfile
method of the global profile
with the application string "Solutions/Sales", then call the Sales
Profile method getAttribute
with an application string of
null and the desired key. This will search only the Sales profile,
and return a null if no value for the key is found.
If a profile attribute may have multiple values for a key, an application
can use the getAttributes
method to retrieve a List that
contains all the values. This method takes an application path string
that may contain "*" as a wildcard. The profile tree is searched downward
for matches on the application path. If the application matches, the
profile is checked for values for the requested key. Any that are found
are added to the result List.
The global profile has one special attribute,
The global profile should ordinarily be configured to be the GlobalProfile class. Besides the normal Profile behavior, it also supports access to the Personal Repository and Group profiles.
Group profiles work pretty much the same way as personal profiles. If you make a
getAttribute
call to the GlobalProfile, it will look through
the profile hierarchy as it normally would. If a value is found, it's
returned as normal. If no value is found, it will start looking in the
group profile data. It will return the first value it finds that matches
the key and application strings.
The group profiles are loaded by the GlobalProfile load() method. It will get a list of the IdentityGroups that the Person object belongs to. It will then try to load a profile for each of those groups. For each group that has a profile, it will add it to the group profile collection. Group profiles may have the same hierarchical structure that the personal profiles have.
The GlobalProfile supports accessing the group profiles by getting the whole
set of them using getGroupProfiles()
which returns all group
profiles, or getGroupProfile(String name)
which returns a profile
for a specific group.
<Profile Application="global" url="ldap://d5296.us.sas.com:389" class="com.sas.services.user.Profile"/> |
loadProfile
method. When loadProfile is called, the
configuration information is looked up and an instance of the
configured profile class is created. It then tries to find a handle
to the repository specified by the url, and calls the Profile
object's load
method. The generic Profile class
creates an instance of ProfileStoreInterface based on the
protocol of the repository (currently, there are OMIProfileStore
and LDAPProfileStore classes), that handles reading and writing
data to the backend.
The simplest model for applications is to create their specific profiles
as subprofiles of the global profile. Once this is done, the application
profile will be automatically loaded when the UserContext is created with
the UserService.newUser()
method. This way, the profile won't
need to be explicitly loaded after it's created.
Example
ProfileInterface po = userContext.getProfile(); // get global Profile try { ProfileInterface cpo = po.getProfile( "Myapp" ); } catch( ServiceException servExcept ) { // It looks like the application profile doesn't exist, so create it ProfileInterface newProfile = new Profile("Myapp"); // create the new profile object try { po.createSubprofile( newProfile ); // create profile in backend repository po.addProfile( "Myapp", newProfile, true ); // Add to global profile now. } catch( Throwable t ) { t.printStackTrace( System.out ); { // You can set default values here, then persist the changes. }
If your application's profile has complex objects, or you want to
provide specific methods for accessing attributes rather than having
to use a key (that is, getBackground() rather than
getAttribute("background"), you'll have to write a subclass of
com.sas.services.user.Profile that provides those functions. You'll
also have to override the load
and persist
methods that handle reading and writing the data to the persistent
store.
A process by which the identity of a user is verified. | ||
A collection of services within which a credential set is valid. This collection is assigned a name, which should be used consistently through the enterprise. | ||
An identity (usually a user ID), and a credential (password or certificate), along with an authentication domain name which can be used to authenticate a user. |
In order to create a new UserContext, the simplest procedure is to acquire
a userID and password, and call the UserService newUser
method.
You will also need to provide an authentication domain name within which the
ID and password are valid. The user service will use the Security Service to
attempt to authenticate the user. If this succeeds, any credential sets in
the repository(s) the user may have authenticated with are retrieved and stored
in the UserContext. Also, the handles to the repository(s) are stored in
the UserContext. If the authentication fails, a null is returned.
It's possible that the authentication could succeed, but other UserContext initializations may fail. In that case, a UserInitializationException is thrown. The UserInitializationException contains the partially initialized UserContext and a collection of Exceptions that occurred during the initialization process. Likely exceptions are auto connect failures and profile load failures. Applications can catch the UserInitializationException and get the UserContext via the getUser() method and proceed. It's strongly recommended, though, that the Exceptions be logged so that any underlying problems can be fixed.
The user identity is a credential set used as input to the authentication service. A user may have several identities for accessing a variety of external services (data repositories, servers, etc.). An identity is comprised of a principal name, a credential, and the name of the security domain that the identity should be valid in. This is used to reference credentials against services and resources to find an appropriate credential set to perform an operation. While the domain name is an arbitrary string, care should be taken to be consistent across an enterprise.
Authentication is performed using JAAS compatible classes. Login modules currently exist for the SAS Metadata Server and LDAP. These login modules authenticate the user, and initialize the UserContext by collecting available credential sets from the repository, and storing the repository handle. These are then available for use by the applications.
The configuration file for the login modules (login.config) contains the configured domain name for each module. Be sure that the domain you configure for at least one login module matches the domain that use on the newUser method. If not, the login will fail.
The user credential sets are protected from unauthorized access by use of the Java security classes. Credential sets in an identity can be protected using the security policy manager, and granting the CredentialPermission "readCredential" permission to the appropriate classes. The UserContextInterface methods that get identities will verify that either the current user (as set by a Subject.doAs() call), is the same as the Subject in the context that identities are being read from, or the current user has the CredentialPermission with the "readCredential" action. To grant this permission, add the following to the policy or auth.policy file:
grant { com.sas.services.user.CredentialPermission "readCredential"; }; |
This permission can be granted to a specific codebase or user. Check the JAAS documentation for more information.
Below is some sample code which uses the definitions that are created in the bootstrap XML to retrieve a configured user context, and verify that it authenticates successfully.
/* * The Portal User should have been defined in the initialization * for the user service. Try to get the user context. */ UserContextInterface user = _userService.getUser( "Portal User" ); if ( user != null ) { System.out.println (" got portal user " ); } /* * We should now have a fully initialized UserContext for this * user. We can do searches, use its profile, etc. as we * would for any other user. */ |
It is also possible to create users in the application. Below is a sample of creating a user at run time, simulating a user connecting to the application.
/* * Have the User Service create new user context. The userID and * password, would, of course, usually come from the user, and the * domain string would normally come from the application * configuration. */ UserContextInterface userMe = null; try { userMe = _userService.newUser( "testUser", "testPW", "Alpine" ); } catch( UserInitializationException uiex ) { Exception[] exceptions = uiex.getExceptions(); for( int i = 0; i < exceptions.length; i++ ) { Exception exception = exceptions[i]; exception.printStackTrace( System.out ); } userMe = uiex.getUser(); } // If the authentication worked, do some work to get user // information. if ( userMe != null ) { /* * If the LDAP authentication service was used, some information * was added to the profile to the global section. */ System.out.println( "I authenticated" ); System.out.println( "My name is : " + userMe.getName() ); System.out.println( "My title is : " + userMe.getProfile().getAttribute( null, "title" ) ); /* * Get the portal profile as defined by the initialization file. */ ProfileInterface po = _userService.loadProfile( userMe, "Portal" ); /* * if we got the profile, print out the sasportalpersonalwindows * just to prove it. */ if ( po != null ) { Enumeration e = po.getValues( "sasportalpersonalwindows" ); while( e.hasMoreElements() ) { System.out.println( "Personal window: " + (String)e.nextElement() ); } } } else { /* * Authentication didn't work. Draw your own conclusions. */ System.out.println( "I've apparently been fired" ); } |
|
Foundation |
|
| |||||||||||
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |