Skip to content
This repository has been archived by the owner on Dec 12, 2018. It is now read-only.
ecrisostomo edited this page Oct 10, 2012 · 33 revisions

Stormpath Java SDK

The Stormpath Java SDK allows any JVM-based application to easily use the Stormpath cloud Identity Management service for all authentication and access control needs.

When you make SDK method calls, the calls are translated into HTTPS requests to the Stormpath REST+JSON API. The Stormpath Java SDK therefore provides a clean object-oriented paradigm natural to JVM developers and alleviates the need to know how to make REST+JSON requests. Any JVM-based programming language can use the Stormpath Java SDK (e.g. Java, Groovy, Scala, Clojure, Jython, JRuby, etc.)

Quick Start

  1. Add the Stormpath Java SDK .jars to your application using Maven, Ant+Ivy, Grails, SBT or whatever Maven Repository-compatible tool you prefer:

     <dependency>
         <groupId>com.stormpath.sdk</groupId>
         <artifactId>stormpath-sdk-api</artifactId>
         <version>0.5.0</version>
     </dependency>
     <dependency>
         <groupId>com.stormpath.sdk</groupId>
         <artifactId>stormpath-sdk-httpclient</artifactId>
         <version>0.5.0</version>
         <scope>runtime</scope>
     </dependency>
    
  2. Ensure you have an API Key so your application can communicate with Stormpath. Store your API Key file somewhere secure (readable only by you), for example:

     /home/myhomedir/.stormpath/apiKey.properties
    

    This file's contents should contain the following name/value pairs (using your own values of course):

     $ cat /home/myhomedir/.stormpath/apiKey.properties
     
     apiKey.id = YOURAPIKEYIDHEREREPLACEME
     apiKey.secret = YoUrReAlLyLongSecretValueHereReplaceMeWithYourValue
    

    Also change the file permissions to ensure only you can read the file:

     $ chmod go-rw /home/myhomedir/.stormpath/apiKey.properties
    

    More information on different ways to configure and retrieve information from this file can be found in the Client Builder API documentation.

  3. Configure your application to create a Stormpath SDK Client instance based on your API Key. The Client instance is your starting point for all operations with the Stormpath service. For example:

     import com.stormpath.sdk.client.*;
     ...
     
     String path = System.getProperty("user.home") + "/.stormpath/apiKey.properties";
     Client client = new ClientBuilder().setApiKeyFileLocation(path).build();
    
  4. Use the Client instance to interact with your tenant data, such as Applications, Directories, and Accounts:

     Tenant tenant = client.getCurrentTenant();
     
     ApplicationList applications = tenant.getApplications();
     
     for (Application application : applications) {
         System.out.println("Application " + application.getName());
     }
     
     DirectoryList directories = tenant.getDirectories();
     
     for (Directory directory : directories) {
         System.out.println("Directory " + directory.getName());
     }
    

Client

The root entry point for SDK functionality is the Client instance. Using the Client instance, you can access all of your tenant's data, such as applications, directories, groups, accounts, etc.

Preferred Configuration

There are different ways to create a Client instance to interact with your resources. The preferred mechanism is by reading a secure apiKey.properties file as shown above in the Quick Start, sections 2 and 3, where the ClientBuilder implementation is being used:

import com.stormpath.sdk.client.*;
...

String path = System.getProperty("user.home") + "/.stormpath/apiKey.properties";
Client client = new ClientBuilder().setApiKeyFileLocation(path).build();

This is heavily recommended if you have access to the file system.

Single URL Configuration

The above QuickStart assumes you have easy access to an apiKey.properties file. Some applications however may not have access to the file system (such as Heroku) applications. In these cases, you can also create a Client instance using a single URL, where often the URL is available as an environment variable (e.g. System.getenv()).

This technique requires embedding the API Key ID and Secret as components in a URL. This allows you to have a single URL that contains all necessary information required to construct a Client.

WARNING: Do not use this technique if you have access to a file system. Depending on the environment, environment variables are less secure than reading a permission-restricted file like apiKey.properties.

If you do not have access to the file system to read an apiKey.properties file, then this technique might be useful to you:

You can use the ClientApplicationBuilder instead of the ClientBuilder. The ClientApplicationBuilder accepts a single URL of your Application's Stormpath HREF with the API Key information embedded in the URL. For example:

String appHref = "https://apiKeyId:[email protected]/v1/applications/YOUR_APP_UID_HERE";

Ensure that the apiKeyId and apiKeySecret components are URL-encoded.

Then you can acquire the ClientApplication using the ClientApplicationBuilder to obtain a Client and an Application:

import com.stormpath.sdk.client.*;
import com.stormpath.sdk.application.*;
...
...
ClientApplication clientApplication = new ClientApplicationBuilder().setApplicationHref(appHref).build();

Client client = clientApplication.getClient();
Application application = clientApplication.getApplication();

The ClientApplicationBuilder is a powerful utility that can be used in different ways, including all of the ClientBuilder functionalities. To learn more about its usage you can read the ClientApplicationBuilder API documentation.

API Key Configuration

Another way to create a Client is by creating an ApiKey instance with the API credentials and passing this instance to create the Client instance:

import com.stormpath.sdk.client.*;
...
...
ApiKey apiKey = new ApiKey("apiKeyId", "apiKeySecret");
Client client = new Client(apiKey);

WARNING: DO NOT specify your actual apiKey.id and apiKey.secret values in source code! They are secure values associated with a specific person. You should never expose these values to other people, not even other co-workers.

Only use this technique if the values are obtained at runtime via a configuration mechanism that is not hard-coded into source code or easily-visible configuration files.

Error Handling

Errors thrown from the server are translated to the runtime ResourceException. This applies to all the requests to the Stormpath API endpoints.

For example, when getting the current tenant from the client you can catch any error that the request might produce the following way:

try {

    client.getCurrentTenant();

} catch (ResourceException re)
{
    System.out.println("Message: " + re.getMessage());
    System.out.println("HTTP Status: " + re.getStatus()); 
    System.out.println("Developer Message: " + re.getDeveloperMessage());
    System.out.println("More Information: " + re.getMoreInfo());
    System.out.println("Code: " + re.getCode());
}

Managing Directories

Retrieving a Directory

To retrieve a specific Directory you will need its UID. After you have the Directory's UID it can be loaded as an object instance by retrieving it from the server, using the data store:

import com.stormpath.sdk.client.*;
import com.stormpath.sdk.directory.*;
import com.stormpath.sdk.ds.*;
...
...
DataStore dataStore = client.getDataStore(); 
String href = "https://api.stormpath.com/v1/directories/DIR_UID_HERE";
Directory directory = dataStore.getResource(href, Directory.class); 

Listing Directories

To list all directories on the current tenant, we loop the directories aggregate that we get from the current tenant:

import com.stormpath.sdk.client.*;
import com.stormpath.sdk.directory.*;
import com.stormpath.sdk.tenant.*;
...
...
Tenant tenant = client.getCurrentTenant();
    
DirectoryList directories = tenant.getDirectories();

for (Directory dir : directories) {

    System.out.println("Directory " + dir.getName());
    System.out.println("Directory Description " + dir.getDescription());
    System.out.println("Directory Status " + dir.getStatus());
}

Editing Directories

To edit directories, we use the "setters" of an existing Directory's instance to set the values we want and call the save method:

import com.stormpath.sdk.directory.*;
import com.stormpath.sdk.resource.Status;
...
...
directory.setStatus(Status.DISABLED);  // the Status enum class provides the valid status' constants
directory.setName("New Directory Name");
directory.setDescription("New Directory Description");

directory.save();

Managing Applications

Creating Applications

To edit applications, we use the "setters" of a new Application's instance to set the values we want. After this, we create the application from the tenant, the following way:

import com.stormpath.sdk.tenant.*;
import com.stormpath.sdk.application.*;
...
...
Tenant tenant = client.getCurrentTenant();

Application application = client.getDataStore().instantiate(Application.class);
application.setName("Application Name");
application.setDescription("Application Description");

application = tenant.createApplication(application);

Retrieving an Application

To retrieve a specific Application you will need its UID. After you have the Application's UID it can be loaded as an object instance by retrieving it from the server, using the data store:

import com.stormpath.sdk.ds.*;
import com.stormpath.sdk.application.*;
...
...
DataStore dataStore = client.getDataStore(); 
String href = "https://api.stormpath.com/v1/applications/APP_UID_HERE";
Application application = dataStore.getResource(href, Application.class); 

Listing Applications

To list all applications on the current tenant, we loop the applications aggregate that we get from the current tenant:

import com.stormpath.sdk.client.*;
import com.stormpath.sdk.application.*;
import com.stormpath.sdk.tenant.*;
...
...
Tenant tenant = client.getCurrentTenant();
    
ApplicationList applications = tenant.getApplications();

for (Application app : applications) {

    System.out.println("Application " + app.getName());
    System.out.println("Application Description " + app.getDescription());
    System.out.println("Application Status " + app.getStatus());
}

Editing Applications

To edit applications, we use the "setters" of an existing Application's instance to set the values we want and call the save method:

import com.stormpath.sdk.application.*;
import com.stormpath.sdk.resource.Status;
...
...
application.setStatus(Status.DISABLED);  // the Status enum class provides the valid status' constants
application.setName("New Application Name");
application.setDescription("New Application Description");

application.save();

Managing Accounts

Creating Accounts

To create accounts, we use the "setters" of a new Account's instance to set the values we want. Then, we create the account from a Directory the following way:

import com.stormpath.sdk.account.*;
import com.stormpath.sdk.directory.*;
...
...
String href = "https://api.stormpath.com/v1/directories/DIR_UID_HERE";
Directory directory = client.getDataStore().getResource(href, Directory.class);

Account account = client.getDataStore().instantiate(Account.class);
account.setGivenName("Given Name");
account.setSurname("Surname");
account.setUsername("Username");
account.setEmail("Email");
account.setMiddleName("Middle Name");
account.setPassword("Password");

account = directory.createAccount(account);

If you want to override the registration workflow (account verification via email link) and have the account created with ENABLED status right away, you may pass false as second argument, the following way:

account = directory.createAccount(account, false);

If you want to associate the newly created account to a Group (groups will be detailed later in this document), you can do it the following way:

account.addGroup(group);

Retrieving an Account

To retrieve a specific Account you will need its UID. After you have the Account's UID it can be loaded as an object instance by retrieving it from the server, using the data store:

import com.stormpath.sdk.ds.*;
import com.stormpath.sdk.account.*;
...
...
DataStore dataStore = client.getDataStore(); 
String href = "https://api.stormpath.com/v1/accounts/ACCOUNT_UID_HERE";
Account account = client.getDataStore().getResource(href, Account.class); 

Verifying Accounts

To verify an Account (e.g. set status to ENABLED via link sent to account's email), when the account verification workflow is enabled for the account's directory, the token needs to be obtained from the link that the account's holder receives in his email inbox. This is achieved by implementing the following logic:

import com.stormpath.sdk.tenant.*;
import com.stormpath.sdk.account.*;
...
...
String verificationToken = // obtain it from query parameter, according to the workflow configuration of the link

Tenant tenant = client.getCurrentTenant();

// when the account is correctly verified it gets activated and that account is returned in this verification
Account account = tenant.verifyAccountEmail(verificationToken);

Authenticating Accounts

To authenticate an account we need to have the Application to where the account will be authenticated against. After we have the Application, the account is authenticated by providing the username and password the following way:

import com.stormpath.sdk.application.*;
import com.stormpath.sdk.account.*;
import com.stormpath.sdk.authc.*;
...
...
String href = "https://api.stormpath.com/v1/applications/APP_UID_HERE";
Application application = client.getDataStore().getResource(href, Application.class);

// when the account is authenticated, it produces an AuthenticationResult instance
AuthenticationResult authResult = application.authenticateAccount(new UsernamePasswordRequest('username', 'password'));

// from the AuthenticationResult instance we obtain the Account we just authenticated
Account account = authResult.getAccount();

Listing Accounts

To list accounts you need a directory or a group.

If you need to list the accounts that belong to a specific directory, this is how you do it:

import com.stormpath.sdk.directory.*;
import com.stormpath.sdk.account.*;
...
...
AccountList accounts = directory.getAccounts();
    
for (Account acc : accounts) {

    System.out.println("Given Name " + acc.getGivenName());
    System.out.println("Surname " + acc.getSurname());
    System.out.println("Account Status " + acc.getStatus());
    System.out.println("Username " + acc.getUsername());
    System.out.println("Email " + acc.getEmail());
    System.out.println("Middle Name " + acc.getMiddleName());
}

Similarly, getting the accounts from a group works the following way:

AccountList accounts = group.getAccounts();

Editing Accounts

To edit accounts, we use the "setters" of an existing Account's instance to set the values we want and call the save method:

import com.stormpath.sdk.account.*;
import com.stormpath.sdk.resource.Status;
...
...
account.setStatus(Status.DISABLED);  // the Status enum class provides the valid status' constants
account.setGivenName("New Given Name");
account.setSurname("New Surname");
account.setUsername("New Username");
account.setEmail("New Email");
account.setMiddleName("New Middle Name");

account.save();

If you want to add a group to an account, do the following:

account.addGroup(group);

Reseting Account's Password

To use the password reset workflow you need to create a token that will be sent via email to the account's holder, and verify the token which returns the account where the password can be updated. This is done from the Application, like the following example:

import com.stormpath.sdk.application.*;
...
...
String href = "https://api.stormpath.com/v1/applications/APP_UID_HERE";
Application application = client.getDataStore().getResource(href, Application.class);

// creating the password reset token and sending the email
application.sendPasswordResetEmail('username or email');

After the user clicks the link, the password reset token should be obtained from the query string according to the link's configurations that you set on the password reset workflow, and the password can be changed the following way:

import com.stormpath.sdk.application.*;
import com.stormpath.sdk.account.*;
...
...  
String href = "https://api.stormpath.com/v1/applications/APP_UID_HERE";
Application application = client.getDataStore().getResource(href, Application.class);

// getting the Account from the token and changing the password
Account account = application.verifyPasswordResetToken("PASS_RESET_TOKEN");
account.setPassword("New Password");
account.save();

Managing Groups

Retrieving a Group

To retrieve a specific Group you will need its UID. After you have the Group's UID it can be loaded as an object instance by retrieving it from the server, using the data store:

import com.stormpath.sdk.ds.*;
import com.stormpath.sdk.group.*;
...
...
DataStore dataStore = client.getDataStore();
String href = "https://api.stormpath.com/v1/groups/GROUP_UID_HERE";
Group group = dataStore.getResource(href, Group.class);

Listing Groups

To list all groups on a directory or an account, we loop the groups aggregate that we get from a directory or from an account:

import com.stormpath.sdk.group.*;
...
...
GroupList groups = // directory.get_groups or account.get_groups

for (Group grp : groups) {

    System.out.println("Group " + grp.getName());
    System.out.println("Group Description " + grp.getDescription());
    System.out.println("Group Status " + grp.getStatus());
    System.out.println("Group Tenant " + grp.getTenant().getName());
    System.out.println("Group Directory " + grp.getDirectory().getName());
}

Editing Groups

To edit groups, we use the "setters" of an existing Group's instance to set the values we want and call the save method:

import com.stormpath.sdk.account.*;
import com.stormpath.sdk.resource.Status;
...
...
group.setStatus(Status.DISABLED);  // the Status enum class provides the valid status' constants
group.setName("New Group Name");
group.setDescription("New Group Description");

group.save();

If we want to add an existing account to the group, we just do the following:

group.addAccount(account);

Group Membership

A group membership is the relationship between an Account and a Group

Deleting a group membership

A way to delete a group membership is by searching for it by looping the group membership aggregate of an account and, after it's found, retrieve it and delete it:

import com.stormpath.sdk.account.*;
import com.stormpath.sdk.group.*;
...
...
String groupHref = "https://api.stormpath.com/v1/groups/GROUP_UID_HERE";

String accountHref = "https://api.stormpath.com/v1/accounts/ACCOUNT_UID_HERE";
Account account = client.getDataStore.getResource(accountHref, Account.class);

boolean groupLinked = false;
GroupMembership groupMembership = null;
// looping the group membership aggregate of the account
for (GroupMembership tmpGroupMembership : account.getGroupMemberships()) {

    groupMembership = tmpGroupMembership;
    Group tmpGroup = groupMembership.getGroup();

    // here, we make sure this is the group we're looking for
    if (tmpGroup != null && tmpGroup.getHref().contains(groupHref)) {

        groupLinked = true;
        break;
    } 
}

// if the group was found, we delete it
if (groupLinked) {

    groupMembership.delete();
}