After having completed the first part of this OAuth story, it is now time to implement the second part: the service consumer. While the our service provider made use of the DaliCore module dalicore-oauth, the service consumer will use the module dalicore-externalnetwork to make our connection to the service provider easier.
As in part 1, it is probably best to download the sample service consumer application, which will make this tutorial a bit easier to follow.
Manage service consumers
Before we start with the service consumer application itself, we need to be able to register service consumers in our service provider. Create a new class in the service provider application with the name ServiceConsumerHandler
next to the already existing OAuthHandler
class.
@Path("serviceconsumer") @ManagedBean public class ServiceConsumerHandler { @Inject OAuthBean oauthBean; @GET @Produces("text/html") public String create(@QueryParam("name") String name) { if (name != null && ! name.trim().isEmpty()) { DaliServiceConsumer daliServiceConsumer = new DaliServiceConsumer(); daliServiceConsumer.setName(name); daliServiceConsumer.setConsumerKey(StringUtil.getSecureRandomString(16)); daliServiceConsumer.setConsumerSecret(StringUtil.getSecureRandomString(16)); daliServiceConsumer.setStatus(DaliServiceConsumer.Status.ACTIVE); oauthBean.createDaliServiceConsumer(daliServiceConsumer); return "consumer key:" + daliServiceConsumer.getKey() + "
consumer secret:" + daliServiceConsumer.getSecret() + "
"; } else { return "No name provided. Add ?name=service_consumer_name at the end of the URL."; } } }
After redeploying the application, we can create a service consumer by calling http://localhost:8080/oauthprovider/rest/serviceconsumer?name=ServiceConsumerName. The response will show us the service consumer key and secret that we will need later on when connecting to the service provider.
Creating the service consumer application
Now we can start with the creation of our oauth service consumer. Create a new Maven Web Application project in NetBeans.
Maven setup
As in the first part of the series, we need to change the maven pom.xml file so that it will be able to download the LodgON artifacts. Include the following repository in your pom.xml:
<repositories> <repository> <id>lodgon</id> <url>http://maven.lodgon.com/maven2</url> </repository> </repositories>
Afterwards add the following maven dependencies:
<dependency> <groupId>com.lodgon.dalicore</groupId> <artifactId>dalicore-externalnetwork</artifactId> <version>0.9.11-SNAPSHOT</version> </dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-server</artifactId> <version>1.8</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.sun.jersey.contribs.jersey-oauth</groupId> <artifactId>oauth-signature</artifactId> <version>1.8</version> </dependency>
Jersey handler and jsp's
Now we can create a handler that will handle the connection to the service provider. Create a new class called HomeHandler
with the following code:
@Path("home") public class HomeHandler { private static final String PROVIDER_URL = "http://localhost:8080/oauthprovider/rest"; private static final String CONSUMER_KEY = ""; private static final String CONSUMER_SECRET = ""; private static final String CONSUMER_CALLBACK = "http://localhost:8080/oauthconsumer/rest/home/callback"; @Context HttpServletRequest request; @GET public Response home() throws URISyntaxException { ExternalToken accessToken = (ExternalToken) request.getSession().getAttribute("accessToken"); if (accessToken == null) { DaliCoreExternalNetwork externalNetwork = new DaliCoreExternalNetwork(PROVIDER_URL, CONSUMER_KEY, CONSUMER_SECRET); return externalNetwork.connect(CONSUMER_CALLBACK); } else { return Response.ok(new Viewable("/home.jsp", accessToken)).build(); } } @GET @Path("callback") public Response callback(@QueryParam("oauth_token") String requestToken, @QueryParam("oauth_verifier") String verifier) throws URISyntaxException { DaliCoreExternalNetwork externalNetwork = new DaliCoreExternalNetwork(PROVIDER_URL, CONSUMER_KEY, CONSUMER_SECRET); ExternalToken accessToken = externalNetwork.callback(requestToken, verifier); request.getSession().setAttribute("accessToken", accessToken); return Response.seeOther(new URI("/home")).build(); } }
This class contains two entry points. The home
entry point is the URL that is being called to initiate a connection with our service provider. It detects if an access token exists on the active session. If an access token does not exist, we will connect with the dalicore-oauth service provider, by using the utility class DaliCoreExternalNetwork
. The constructor of this class takes three parameters: the URL to the service provider, our consumer key and our consumer secret. Update the static fields at the top with the consumer key and secret you received by creating a service consumer as mentioned previously. When we have an instance of the DaliCoreExternalNetwork
we simply call the connect
method and provide the callback where the user will be redirected to after it authorized the service consumer.
The callback is handled by the second entry point, named callback
. It accepts the request token and a verifier that we will need to request our access token. This can also be done through the DaliCoreExternalNetwork
helper class. By calling the callback method we will finally receive a valid access token which we store on the active session. Finally, we redirect the user back to the home page, which will print our access token information in the browser.
web.xml configuration
Next we need to activate Jersey so our handler will be processed. Create a Standard Deployment Descriptor and put in the following code:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <servlet> <servlet-name>jerseyservlet</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> </servlet> <servlet-mapping> <servlet-name>jerseyservlet</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> </web-app>
JPA Configuration
Finally, we need to configure a connection with the database where the tokens will be stored. Create a persistence.xml file in the directory src/main/resources/META-INF with the following content:
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> <persistence-unit name="oauth_provider_pu" transaction-type="JTA"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <jta-data-source>jdbc/oauthconsumerdb</jta-data-source> <class>com.lodgon.dali.core.entity.Application</class> <class>com.lodgon.dali.core.entity.Content</class> <class>com.lodgon.dali.core.entity.ContentPermission</class> <class>com.lodgon.dali.core.entity.Field</class> <class>com.lodgon.dali.core.entity.Group</class> <class>com.lodgon.dali.core.entity.GroupPermission</class> <class>com.lodgon.dali.core.entity.TypePermission</class> <class>com.lodgon.dali.core.entity.User</class> <class>com.lodgon.dali.core.entity.UserPermission</class> <class>com.lodgon.dali.core.externalnetwork.entity.ExternalToken</class> <class>com.lodgon.dali.core.externalnetwork.entity.OnlineAccount</class> <properties> <property name="eclipselink.ddl-generation" value="create-tables"/> </properties> </persistence-unit> </persistence>
Pre-deployment configuration
Again, just like we did when setting up the service provider, we need to add the JDBC resources to glassfish. Create a file called sun-resources.xml with the following content:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE resources PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 Resource Definitions //EN" "http://www.sun.com/software/appserver/dtds/sun-resources_1_3.dtd"> <resources> <jdbc-connection-pool connection-validation-method="auto-commit" datasource-classname="org.apache.derby.jdbc.EmbeddedDataSource" res-type="javax.sql.DataSource" name="derby_oauthconsumerdb_j2eepool" wrap-jdbc-objects="false"> <property name="ConnectionAttributes" value=";create=true" /> <property name="DatabaseName" value="memory:oauthconsumerdb" /> </jdbc-connection-pool> <jdbc-resource enabled="true" jndi-name="jdbc/oauthconsumerdb" object-type="user" pool-name="derby_oauthconsumerdb_j2eepool"/> </resources>
And add the resources to glassfish by calling the add-resources asadmin command:
$ asadmin add-resources sun-resources.xml
Building and deployment
Finally, you can build and deploy the application by pressing F6. Afterwards point your browser to http://localhost:8080/oauthconsumer/rest/home. Login with any username and password, authorize the service consumer and you should have your access token!