The SafehausLoginModule is pretty useless without using the Guardian API for authorization. As a matter of fact you have to pass in an instance of ApplicationPolicy which is the main application entity in Guardian. This is the entity which is used to access application permissions, roles and profiles.
In this tutorial we show you how to use the Guardian API with the LDAP driver to connect to Triplesec. This information can be used standalone or in combination with the JAAS LoginModile to authenticate and authorize users.

Initializing an ApplicationPolicy Instance

The Guardian API uses ApplicationPolicyDrivers to connect to various sources of policy information. As of this writing there are two kinds of Drivers: LDAP and LDIF drivers. The LDAP driver connects to a Triplesec server via LDAP to acquire the policy information for an application. The LDIF driver loads an LDIF file from disk. This way you can export your application policy from Triplesec and use the LDIF driver for unit test cases in your applications.

The LDAP driver take an LDAP URL and some connection properties. The connection properties are listed below:

Property Name

Purpose

Example Value

applicationPrincipalDN

Used as the principalDn to bind to LDAP Server

appName=demo,ou=Applications,dc=safehaus,dc=org

applicationCredentials

The Application's password to bind with.

'secret'

Below is code which initializes an ApplicationPolicy by connecting to the Triplesec server on the localhost with it's LDAP service running on port 10389. Note that the realm for this example is safehaus.org as it was configured using the Configuration Wizard.

When supplying the connectionUrl you must always use the LDAP base for the realm. If your realm is example.com then you use dc=example,dc=com in your connection URL.

ApplicationPolicy Initialization Code
// -------------------------------------------------------------------
// Setup connectionUrl and connection properties
// -------------------------------------------------------------------

String connectionUrl = "ldap://localhost:10389/dc=safehaus,dc=org";
String appDn = "appName=demo,ou=Applications,dc=safehaus,dc=org";
String password = "secret";

Properties props = new Properties();
props.setProperty( "applicationPrincipalDN", appDn );
props.setProperty( "applicationCredentials", password );

// -------------------------------------------------------------------
// Load the driver and connect to get a new ApplicationPolicy instance
// -------------------------------------------------------------------

ApplicationPolicy policy = null;
try
{
    Class.forName( "org.safehaus.triplesec.guardian.ldap.LdapConnectionDriver" );
    policy = ApplicationPolicyFactory.newInstance( connectionUrl, props );
}
catch ( Exception e )
{
    // handle the exception ...
}

Using An ApplicationPolicy Object

As noted in the JAAS based login tutorial, Authentication Using SafehausLoginModule, you need an ApplicationPolicy object to authenticate using the SafehausLoginModule. Besides this fact you can directly use the Guardian API to enforce access control policies stored and managed by Triplesec for your applications.

You can lookup permissions defined for the application as well as roles. However most importantly you can check to see if a profile has a permission or is in a role. Using these API's your application can check to see if some operation is allowed or if access to a resource is permitted. Below is some code which uses the ApplicationPolicy object above to enumerate the permissions, and roles within an application:

Access Roles and Permissions
System.out.println( "Permissions:" );
Permissions perms = policy.getPermissions();
for ( Iterator ii = perms.iterator(); ii.hasNext(); /**/ )
{
    Permission perm = ( Permission ) ii.next();
    System.out.println( "\t" + perm.getName()  );
}

System.out.println( "Roles:" );
Roles roles = policy.getRoles();
for ( Iterator ii = roles.iterator(); ii.hasNext(); /**/ )
{
    Role perm = ( Role ) ii.next();
    System.out.println( "\t" + role.getName()  );
}

You can also access authorization profiles associated with users. Remember there are several applications managed by the Triplesec. A user may have a different profile for each application with application specific permissions and roles assigned. A user may also have more than one profile for an application. Here's some code that accesses a profile then checks to see if it has certain permissions or is in a role:

Using Profiles
Permission bend = policy.getPermissions().get( "bend" );
Profile mcurie = policy.getProfile( "mcurie" );
if ( mcurie.hasPermission( "fold" ) || mcurie.hasPermission( bend ) ) {
    grantAccess();
}
else {
    throw new AccessDeniedException();
}

// grant access if mcurie is in the required role
if ( mcurie.isInRole( "trusted" ) ) {
    grantAccess();
}
else {
    throw new AccessDeniedException();
}

What's the authentication authorization connection?

You may be asking, "Ok this is fine we can authenticate and authorize but how do we tie them both together effectively in application?"

The answer is all in the Subject. The SafehausLoginModule populates the Subject with a SafehausPrincipal. This principal contains within it a Guardian Profile object for the user. The login module uses the name passed to it via the NameCallback as a profileId. This profileId is used with the policy object provided to lookup the Profile. After the Profile is looked up the SafehausLoginModule figures out what user that Profile belongs to by calling profile.getUser(). Using this user name it attempts to bind to LDAP using the static password, and if provided it uses the HOTP passcode to authenticate against Kerberos.

If authentication succeeds the Profile is packaged into a SafehausPrincipal and stuffed into the Subject. If it fails nothing is put into the Subject and a LoginException is raised. So getting back to the question. Authorization and authentication connect at the point of login. There after the authorization Profile in the authenticated Principal can be used to determine if access should be granted or denied to resources and operations.

For a complete example see the tutorial on logging users with a simple servlet: Simple Demo Servlet Application.

Gimme More Info on the Guardian API!

This was a pretty cursory tutorial on using Guardian. You probably want some javadocs and some kind of extensive User's Guide right? Hope this helps. BTW the Guardian API User's Guide is also available in wiki format.

  • No labels