You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 4 Next »

Try Servlet Tutorial First

Some of these tutorials are additive. You might want to try the Simple Demo Servlet Application tutorial first before tackling this tutorial which introduces policy change event handling.

ApplicationPolicy Setup

Just like the servlet demo application the swing demo connects to Triplesec to acquire an ApplicationPolicy for the demo application. Yes it is using the same application policy information. Basically one can look at the swing demo as a fat version of the thin servlet demo.

The swing application acquires the parameters to get an ApplicationPolicy from a properties file or uses defaults. Here's a look at the main which gets the ApplicationPolicy.

DemoFrame main()
public static void main( String[] args ) throws Exception
{
    // find the properties file or use defaults
    Properties properties = new Properties();
    if ( args.length > 0 )
    {
        File configurationFile = new File( args[0] );
        if ( configurationFile.exists() )
        {
            properties.load( new FileInputStream( configurationFile ) );
            extractConnectionParameters( properties );
        }
        else
        {
            System.err.println( "no such file: " + configurationFile );
            printUsage();
            System.exit( 1 );
        }
    }
    else if ( System.getProperty( "config.properties" ) != null )
    {
        File configurationFile = new File( args[0] );
        if ( configurationFile.exists() )
        {
            properties.load( new FileInputStream( configurationFile ) );
            extractConnectionParameters( properties );
        }
        else
        {
            System.err.println( "no such file: " + configurationFile );
            printUsage();
            System.exit( 1 );
        }
    }

    // initialize the driver and load the application's base policy from the store
    Properties driverProps = new Properties();
    driverProps.setProperty( "applicationPrincipalDN", applicationPrincipalDn );
    driverProps.setProperty( "applicationCredentials", applicationCredentials );
    Class.forName( driver );
    policy = ApplicationPolicyFactory.newInstance( connectionUrl, driverProps );
    login( true );
    DemoFrame demoFrame = new DemoFrame();
    demoFrame.setVisible( true );
}

Looking at the code the extractConnectionParameters() method finds connection parameters and overrides default static values. Yeah not the best way to go but this is a demo (smile). Notice the mechanics of establishing the ApplicationPolicy object. It is almost identical to the Simple Demo Servlet Application code. As a matter of fact the swing application uses the same exact LoginCommand which we used in the servlet. No need to duplicate that code here.

Implementing Login

Again the mechanics are the same as the Simple Demo Servlet Application. The only difference is that guardian is used to iterate through the set of profiles in the application and to present that in a combobox to the user using a LoginDialog.

The LoginDialog is very simple. It has 3 fields. Two password fields and a combobox for the profile to select for logging in. Take a look at the login() method of the DemoFrame:

DemoFrame login()
static boolean login( boolean doExit )
{
    List profileIdList = new ArrayList();
    for ( Iterator ii = policy.getProfileIdIterator(); ii.hasNext(); /**/ )
    {
        profileIdList.add( ii.next() );
    }
    String[] profileStrings = new String[profileIdList.size()];
    profileStrings = ( String[] ) profileIdList.toArray( profileStrings );
    LoginDialog loginDialog = new LoginDialog( profileStrings );
    loginDialog.setVisible( true );
    if ( loginDialog.isLoginSelected() )
    {
        String password = loginDialog.getPassword();
        String profileId = loginDialog.getSelectedProfile();
        String passcode = loginDialog.getPasscode();

        System.out.println( "password = " + password );
        System.out.println( "passcode = " + password );
        System.out.println( "profile = " + profileId );

        boolean isSuccessful = false;
        try
        {
            LoginCommand command = new LoginCommand( profileId, password, realm, passcode, policy );
            isSuccessful = command.execute();
        }
        catch ( LoginException e )
        {
            e.printStackTrace();
        }

        if ( !isSuccessful )
        {
            System.out.println( "Authentication failed for user profile: " + profileId );
            loginDialog.dispose();
            if ( doExit )
            {
                System.exit( 1 );
            }
            return false;
        }
        else
        {
            loginDialog.dispose();
            currentProfile = policy.getProfile( profileId );
            System.out.println( "got profile: " + currentProfile );
            return true;
        }
    }
    return false;
}

Notice the profileId, password, and passcode are extracted from the LoginDialog, which is analogous to the way the servlet extracted these login parameters from the http request object. Here the LoginDialog is similar to the html form used to prompt users for their password and passcode.

These parameters are then used to instantiate a LoginCommand. Then the LoginCommand is executed to get a boolean result. If login succeeds the currentProfile is set with the profile associated with the profileId.

Up to this point the code is logically identical to the code in the servlet demo.

Using PolicyChangeListener to Update Menus

The swing application presents the permissions available to the profile in a menu where the user can select each permission as an operation. Guardian has a new feature that allows applications to listen for changes to their policy. The swing application uses this feature to register for updates and changes the swing menu listing the operations that can be performed by the user dynamically. Basically as soon as an adminstrator changes the permissions for a Profile or alters a Role which the profile depends on, the menus dynamically update.

Guardian's PolicyChangeListener interface is used to register for updates to application policy. The swing application implements this interface in the inner class below:

PolicyChangeListener Implementation
class DemoListener implements PolicyChangeListener
    {
        public void roleChanged( ApplicationPolicy policy, Role role, ChangeType changeType )
        {
            System.out.println( "role changed: " + role );

            if ( currentProfile.isInRole( role.getName() ) )
            {
                currentProfile = policy.getProfile( currentProfile.getProfileId() );
                resetMenus( currentProfile );
            }
        }

        public void profileChanged( ApplicationPolicy policy, Profile profile, ChangeType changeType )
        {
            if ( currentProfile.equals( profile ) )
            {
                resetMenus( profile );
            }
        }

        public void roleRenamed( ApplicationPolicy policy, Role role, String oldName ) {}
        public void permissionChanged( ApplicationPolicy policy, Permission permission, ChangeType changeType ) {}
        public void permissionRenamed( ApplicationPolicy policy, Permission permission, String oldName ){}
        public void profileRenamed( ApplicationPolicy policy, Profile profile, String oldName ){}
    }

All this code does is it checks if the altered profile is the currentProfile. If so it updates the current profile with the modified on delivered to the listener. Then it resets the menus so only operation menu items that the profile has permissions for are displayed. It also updates reloads the current Profile if a dependent role assigned to the Profile is altered. This makes sense since the effective permissions of a Profile are based on its grants, denials and roles.

Registering the Listener

The DemoFrame registers the listener for notifications using the policy within it's constructor. Here's the constructor code:

DemoFrame Constructor
public DemoFrame()
{
    super();
    initialize();
    policy.addPolicyListener( new DemoListener() );
}

Getting the Code and Running It

The swing demo code is also in the Triplesec svn repository at the following URL:

https://svn.safehaus.org/repos/triplesec/trunk/swing-demo/

You can check this code out and build it like so:

svn co https://svn.safehaus.org/repos/triplesec/trunk/swing-demo
cd swing-demo
mvn clean assembly:assembly

The assembly which you just built as opposed to the jar has all the dependent libraries slapped into a single jar with a MANIFEST that makes the jar an executable jar. So now you can run the application like so:

java -jar target/triplesec-swing-demo-0.7.1-SNAPSHOT-app.jar /path/to/properties/file

You can make a properties file with contents like the one below:

sample.properties
realm=EXAMPLE.COM
connectionUrl=ldap://localhost:10389/dc=example,dc=com
applicationCredentials=secret
applicationPrincipalDn=appname=demo,ou=Applications,dc=example,dc=com
driver=org.safehaus.triplesec.guardian.ldap.LdapConnectionDriver

Again make sure you've taken care of your Kerberos Client Configuration settings. And make sure you have Triplesec configured properly for the realm. You're properties file should replace the realm and other settings to match your Triplesec configuration.

Another way to run the swing app is to launch an interactive unit test which fires up an embedded Triplesec instance along with the app using default settings. Note that this will startup Triplesec for the EXAMPLE.COM domain so your Kerberos Client Configuration should be set accordingly. To run this UI test issue the following command and try not to chuckle (smile):

Running Interactive Demo Test
mvn -Dui test
  • No labels