***  This package contains classes that provide Binary Compatibility only, not Source Compatibility  ***

Note:
Extension of the classes in this package is prohibited unless otherwise documented. Similarly, extension or implementation of the interfaces in this package is prohibited except as documented.

Package com.sas.services.security

Perform Authentication against modular authentication providers with user identities.

See:
          Description

Interface Summary
AuthenticationServiceInterface Authentication Service interface.
AuthenticatorInterface Interface for a class to handle authenticating a user identity.
PermissionInterface Permission interface.
RemoteCallbackHandler This interface makes a remote callback handler by extending the CallbackHandler and Remote interfaces.
RemoteCallbackInterface This is a generic interface for remote callbacks.
RemoteNameCallbackInterface Interface for a remote version of the NameCallback defined in the javax.security.auth.callback package.
RemotePasswordCallbackInterface Interface for a remote version of the PasswordCallback defined in the javax.security.auth.callback package.
 

Class Summary
AuthenticationService The Authentication Service class.
Challenger The Challenger class helps bridge the non-remote JAAS callback classes with the remote PFS versions of the callbacks.
GetSubject This class has only one purpose: To copy a user's Subject across a remote interface.
LoginCallbackHandler Login callback handler.
RemoteNameCallback This is an instance of a NameCallback that's remoteable.
RemotePasswordCallback This is an instance of a PasswordCallback that's remoteable.
SecurityUtil  
 

Exception Summary
BadHostLoginServiceException This exception gets thrown if the authentication process detects that an "unknown host" error occurred while attempting authentication.
ConnectRefusedLoginServiceException This exception gets thrown if the authentication process detects that a "connection refused" network error occurred while attempting authentication.
CredentialLoginServiceException This exception gets thrown when a user attempts to authenticate, but the authentication fails due to a bad user ID or password.
ExpiredPasswordLoginServiceException  
LoginServiceException This is an exception that gets thrown when a user attempts to get authenticated, but it fails for some reason.
NetworkLoginServiceException This exception gets thrown when a user attempts to authenticate, and the authentication fails because of network problems.
 

Package com.sas.services.security Description

Perform Authentication against modular authentication providers with user identities.

Security Service

Overview

The Authentication Service returns an Authenticator object that can be used to authenticate a user's credentials. The authentication service uses the JAAS classes and interfaces to provide a pluggable authentication mechanism. It can also return a collection of the authentication domains that are defined in the login.config file.

Model

A well-defined user identity should have a principal, credential and domain. An authentication domain is an arbitrary string that represents the scope within which a credential set is valid. For instance, an authentication domain may be a Windows domain, an NIS domain, or an LDAP server. While the string that represents the authentication domain is arbitrary, it's important to be consistent for single sign on to work effectively.

Depending on the type of authentication being performed, principals and credentials may be as simple as a user id and password.

The Foundation Services provide a single sign on environment by accessing user credentials that are stored in metadata sources and saving them in the UserContext of an authenticated user. When resources are accessed, the credentials are requested from the UserContext by domain name. If the credential exists for the domain, it is used and the resource accessed without requiring input from the user.

Credentials are stored in the OMR metadata store as Login objects associated to the Person object they belong to. In LDAP, they are stored as SasLogin objects with a sasReferenceDn or sasAllowedClientDn that matches the authenticated user's. When the user authenticates, these credentials are retrieved and saved for possible use during the user's session.

Interface

The interface to the authentication service will return an authenticator. The authenticator interfaces to the JAAS classes to perform the authentication. The parameters to the authenticate method are the UserContext that represents the user being authenticated, the UserIdentity with the credentials to authenticate, and a Map containing options. The options may include any information that may be required to complete a specific authentication operation (like a host, port, LDAP base, etc.).

The authentication service configuration comes from a login module configuration file and a user policy file. The login configuration file should look like:

 PFS {
    com.sas.services.security.login.LdapLoginModule optional host=d5296.us.sas.com "port"="389" 
                                                             "privilegedUser"="cn=Alpine Man" 
                                                             "privilegedPassword"="superpr1v"
                                                             "base"="ou=People,o=Alpine Airlines,c=US"
                                                             "groupbase"="ou=Groups,o=Alpine Airlines,c=US"
                                                             "loginbase"="o=Alpine Airlines,c=US"
                                                             "domain"="ldap"
                                                             "debug"="false";
    com.sas.services.security.login.OMILoginModule  optional host=alphost.alpine.com "port"="5713"
                                                             "domain"="WINNT"
                                                             "base"="repository"
                                                             "encrypt"="false"
                                                             "debug"="false";
 };
 

The login modules take a domain name as an option. The login module will ignore requests to authenticate to a domain other than the one they are configured for. For instance, with the configuration given above, a request to authenticate to domain "WINNT" wil be ignored by the LDAP module and processed by the OMI module.

For the OMILoginModule, the base is the name or ID of the default repository to look in for metadata. This is important because after authentication, the UserContext will have a handle to this server, and this default base will be set for all searches.

The OMILoginModule also has the ability to request an encrypted connection to the metadata server for the authentication process. This can be useful because if single sign on credentials are maintained in the repository, they will be passed across the network as part of this process. Set the "encrypt" option to "true" to enable this feature.

The OMILoginModule can also automatically append the domain to the userid. This is really only useful in a Windows environment. If the configured domain is the same as the Windows network domain name, this can be useful. If the user only enters "myuser" as the id, the login module will append the domain so it looks like "myuser@domain". If the user has a local account with the same id as the domain account, it can be ambiguous, and the authentication will not work as expected. This disambiguates the login. To enable this function, set the "domainQualifyUid" option to "true".

Both the LdapLoginModule and OMILoginModule have the ability to output some debugging information. Set the "debug" option to "true" to enable the debugging output.

User Policy and Subject switching

The user policy file should resemble:
 /** Subject-Based Access Control Policy for the JAAS Sample Application **/
 grant  principal com.sas.services.security.login.PFSPrincipal "*" {
         permission java.io.FilePermission "C:\\BIP\\Services\\-", "read";
         permission java.lang.RuntimePermission "shutdownHooks";
         permission java.lang.RuntimePermission "setFactory";
         permission java.io.FilePermission "C:\\BIP\\Services\\Config\\discovery\\Log\\-", 
                                           "read, write, delete";
         permission java.net.SocketPermission "*.sas.com", "accept, connect, resolve";
         permission java.net.SocketPermission "localhost", "accept, connect, resolve";
         permission java.security.SecurityPermission "getProperty.combiner.provider";
         permission java.util.PropertyPermission "java.security.auth.debug", "read";
         permission javax.security.auth.AuthPermission "getSubject";
         permission java.security.SecurityPermission "getDomainCombiner";
         permission javax.security.auth.AuthPermission "createLoginContext";
         permission javax.security.auth.AuthPermission "getLoginConfiguration";
         permission java.security.SecurityPermission "getProperty.login.configuration.provider";
         permission java.security.SecurityPermission "getProperty.policy.allowSystemProperty";
         permission java.util.PropertyPermission "java.security.auth.login.config", "read";
         permission java.security.SecurityPermission "getProperty.login.config.url.1";
         permission javax.security.auth.AuthPermission "modifyPrincipals";
         permission javax.security.auth.AuthPermission "modifyPrivateCredentials";
         permission javax.security.auth.AuthPermission "doAs";
         permission javax.security.auth.AuthPermission "modifyPrivateCredentials";
         permission com.sas.services.user.CredentialPermission "readCredential";
 };
 

All principals that are generated by the Foundation Services authentication process will be of class com.sas.services.security.login.PFSPrincipal. The principal name will be the userid that was authenticated, appended with "@" and the domain they authenticated in. For instance, if a user with an id of "alpine1" authenticated in domain "WINNT", it would have a principal added to the Subject of "alpine1@WINNT". This principal can be used in the policy file to grant specific permissions.

This policy file gives any user that authenticates within the PFS environment permissions to perform the basic tasks to authenticate, create services, search repositories, etc. In order to allow access to a specific user, replace the "*" in the principal with a principal string.

The subject-based policy file grants permissions to a specific principal, or principal class, but in order to set the security context to a specific user, the application must do a Subject.doAs(), or Subject.doAsPrivileged(). To do that, it needs the user's Subject object. Since the Subject isn't remotable, or serializable, in order to get the Subject in the Foundation Services environment, use the GetSubject class's getSubject method. This will create a Subject in the local JVM with the User's principals and credentials.

Credential Challenging

In a single sign on environment, there will be times that resources are requested in the course of a user session for which no credential exists in the UserContext. The UserService can be set up to challenge the user for these credentials. Again, the JAAS callbacks that get user names and passwords are not remotable, so Foundation Services classes have to provide a means to perform this task in a distributed manner.

This is where the Challenger class comes in. It provides a remote interface to a callback mechanism that acts as a helper to the JAAS callback classes. A client can implement the standard javax.security.auth.callback.CallbackHandler interface and construct a Challenger object, passing itself in on the constructor. The Challenger can then be used on the UserService.setChallengeCallback() method to set the challenge callback. The Challenger class will get the remote callbacks, re-construct them as standard JAAS callbacks, and pass them to the client handler. When the client has processed them, Challenger will re-construct the remote callbacks with the values filled in by the handler, and return them to the caller.

In this example, A Challenger is created, and used to set up the challenge callback in the User Service. Connections are then made to two repositories. When the connection is made to the first, the challenge callback is made for the credentials to the domain "WINNT". When the second connection is made, no challenge is made because it's in the same authentication domain. Then a credential is requested explicitly in the application.
 public class ChallengeSample
     extends UnicastRemoteObject
     implements PrivilegedAction, RemoteCallbackHandler
 {
     public void useService()
     {
         try
         {
             /*
              * The Portal User should have been defined in the initialization
              * for the user service.  Try to get the user context.
              */
             Challenger chall = new Challenger( this );
             _userService.setChallengeCallbackHandler( chall );
             UserContextInterface user = _userService.getUser( "Portal User" );
             if ( user != null )
             {
                 System.out.println("Creating connection to Test2 repository");
                 _informationService.connect( user, "Test2" );
                 System.out.println("Creating connection to Test3 repository" );
                 _informationService.connect( user, "Test3" );
                 UserIdentityInterface ident = user.getIdentityByDomain( "testDomain", true );
                 if ( ident != null )
                 {
                     System.out.println(" Got Identity");
                 }
                 else
                 {
                     System.out.println(" Got null for identity");
                 }
             }
         }
         catch( Throwable t )
         {
             com.sas.util.ChainedException.printStackTrace( t, System.out, true );
         }
         return;
     }
     public void handle( Callback[] callbacks)
         throws UnsupportedCallbackException, RemoteException
     {
         for( int i = 0; i < callbacks.length; i++ )
         {
             Callback callback = callbacks[i];
             if ( callback instanceof NameCallback )
             {
                 String prompt = ((NameCallback)callback).getPrompt();
                 System.out.println( prompt );
                 StringBuffer name = new StringBuffer();
                 try
                 {
                     int c = System.in.read();
                     while( c != 0x0d )
                     {
                         name.append( (char)c );
                         c = System.in.read();
                     }
                     ((NameCallback)callback).setName( name.toString() );
                 }
                 catch( IOException ioe )
                 {
                 }
             }
             if( callback instanceof PasswordCallback )
             {
                 try
                 {
                     if ( System.in.available() > 0 )
                     {
                         System.in.skip( System.in.available() );
                     }
                 }
                 catch( java.io.IOException ioex )
                 {
                 }
                 String prompt = ((PasswordCallback)callback).getPrompt();
                 System.out.println( prompt );
                 StringBuffer name = new StringBuffer();
                 try
                 {
                     int c = System.in.read();
                     while( c != 0x0d )
                     {
                         name.append( (char)c );
                         c = System.in.read();
                     }
                     ((PasswordCallback)callback).setPassword( name.toString().toCharArray() );
                 }
                 catch( IOException ioe )
                 {
                 }
             }
         }
     }
 }
 


***  This package contains classes that provide Binary Compatibility only, not Source Compatibility  ***

Note:
Extension of the classes in this package is prohibited unless otherwise documented. Similarly, extension or implementation of the interfaces in this package is prohibited except as documented.


Copyright © 2009 SAS Institute Inc. All Rights Reserved.