Technistas

Matthew D. Laudato writes about software and technology

Posts Tagged ‘Java

Building an OAuth enabled website using Java

leave a comment »

For me, it’s always been about the APIs. I write them. I use them. I have built and continue to grow my career around them. So as it became clear over the past few years that OAuth has become the de facto standard for API authentication, I took the plunge and figured out how to do practical things with OAuth-based APIs. Since Java is my preferred language, and since I’m now the Product Manager at Constant Contact for the Platform and Partner Integrations, the natural path for my latest project was to build a website using Java that lets users authenticate to Constant Contact via OAuth.

That said, here’s the basics of the application and how it works. The technology stack looks like this:

Web UI: HTML, CSS, JavaScript
Application Services: Java Servlets, JavaScript (Ajax), Scribe-Java (OAuth Java library), REST calls to the Constant Contact API
Database (for storing OAuth tokens and secrets): Hibernate, MS-SQL Server

These are all tools that should be in any programmers toolbox, so the application also serves as a good training app and sample code if you’re trying to get familiar with this stack. The code is available on Github (you do have a Github account, don’t you??). Just fork my repo and you should be ready to go.

Since the main point of this article building an OAuth based website, let’s get right into it. If you want your users to display their data on your website, you as the website owner must let your users grant access to their data. In my case, the data is coming from Constant Contact, so I implemented what is known as the ‘web flow’ for authentication. The flow uses a series of callbacks and goes roughly like this:

– Get a request token from Constant Contact
– Redirect the user to Constant Contact’s OAuth endpoint and ask the end user to authenticate and grant access to their data
– Exchange the authenticated request token for a valid access token and secret and have OAuth redirect the user back to your site.

Now, most of us are not hard-core security programmers, and trust me, if you (like me) prefer to focus on the functionality of your app and not on plumbing, you should use an OAuth library. In my case I chose scribe-java, an excellent open source library for Java OAuth programmers. I submitted the Constant Contact API to the project so that the rest of you can easily authenticate to Constant Contact. You can get scribe-java from github at this url.

I handle the callbacks through two Java servlets. AuthServlet.java makes the initial request for an OAuth Request token, and if successful, redirects to Constant Contact to let the user authenticate and grant access. The basic code looks like this:


OAuthService service = new ServiceBuilder()
.provider(ConstantContactApi.class)
.callback("http://localhost:8080/CTCTWeb/OAuthCallbackServlet.do")
.apiKey(apiKeyProperties.getProperty("apiKey"))
.apiSecret(apiKeyProperties.getProperty("apiSecret"))
.build();
httpsession.setAttribute("oauth.service", service);

Token requestToken = service.getRequestToken();
httpsession.setAttribute(“oauth.request_token”, requestToken);

String confirmAccessURL = service.getAuthorizationUrl(requestToken);

System.out.println(confirmAccessURL);
try {
res.sendRedirect(res.encodeRedirectURL(confirmAccessURL));
} catch (Exception e) {
System.out.println(e.getMessage());
}

 

The simplicity of the code is due to scribe-java. A couple of things to notice. First, we tell scribe-java what the callback URL is when we create the service object. Second, we store the request_token in the httpsession object. This isn’t strictly necessary (we could just store the request token secret, and then reconstruct the request token in the callback), but it is convenient. The reason for this has to do with the scribe-java Token class – it isn’t really a Token per-se, it’s a token-secret pair. I suspect that the author of the library did it this way because token-secret pairs are ubiquitous in OAuth. In any case, when the callback is invoked, it winds up in OAuthCallbackServlet.java. The relevant code looks like this:


String oauth_token = req.getParameter("oauth_token");
String oauth_verifier = req.getParameter("oauth_verifier");
String username = req.getParameter("username");

if (oauth_verifier.length() > 0) {
Verifier verifier = new Verifier(oauth_verifier);

HttpSession httpsession = req.getSession(true);
OAuthService service = (OAuthService) httpsession.getAttribute(“oauth.service”);
Token requestToken = (Token) httpsession.getAttribute(“oauth.request_token”);
httpsession.setAttribute(“username”, username);

Token accessToken = service.getAccessToken(requestToken, verifier);
httpsession.setAttribute(“oauth.access_token”, accessToken);

Long accessTokenId = null;
AccessToken at = new AccessToken();
at.setLoginName(username);
at.setAccessToken(accessToken.getToken());
at.setSecret(accessToken.getSecret());
Date dt = new Date();
Timestamp ts = new Timestamp(dt.getTime());
at.setModifiedDate(ts);

Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
accessTokenId = (Long) session.save(at);
transaction.commit();
} catch (HibernateException e) {
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
}

Again, refer to the full source code on github. There’s several things going on here. First, the entry point to the call back is a servlet URL, which the Constant Contact OAuth implementation has called with three parameters. The oauth_token is the same request token that you generated earlier (but just the token, not the secret). Because I stored the request-token/secret pair earlier, I just ignore this parameter (but see the earlier comment – you could store the secret and then reconstruct the scribe-java Token object). The verifier is a string that the OAuth server creates when the user authenticates and then grants access. The magic is in the call to service.getAccessToken, where you trade in the (now verified) request token for a valid access token. Once you have the token, you need to do something with it so that the next time your user visits the website they can access their Constant Contact data. In my case, I opted to store the username, access token and the token secret in a SQL database. The schema for the database is pretty simple, and Hibernate makes it fairly trivial to store and retrieve the token and secret.

That’s about it for now. Happy coding!

– Matt

Advertisements

Written by Matthew D. Laudato

June 28, 2011 at 9:46 pm

Posted in Java, OAuth

Tagged with , , ,

Speedy Java builds slow down productivity

with 2 comments

I never cease to be amazed at how software development management ignores the build problem. In a recent article in SDTimes, Alex Handy reports on a survey undertaken by RedMonk that found Java developers spend nearly 8 minutes per hour doing software builds. In round numbers, that’s an hour a day, 5 hours a week, and for a typical 48 week year, nearly 30 work days every year. Let me repeat that. Your Java developers, who are presumably paid $80-120k per year, are spending 30 days per year staring at their screens waiting for builds. If we take the middle of this range, this is a productivity loss of over $12,000 per year per developer. For a small 5-10 person team, you could hire an extra developer just with the savings from improving your build process.

The article goes on to say that Java developers “have learned to build smaller portions of their projects at a time, or to compile small pieces of code and inject them into running applications”. I’m trying to think of two worse practices in professional software development. If you build a smaller portion of your project, you risk having unsatisfied dependencies, and thus wasting time when your runtime fails to operate properly. Similarly, injecting code into a running application is dangerous even in a test environment for similar reasons – you haven’t spent any time understanding the dependencies, and therefore are at risk of dependency-related failures.

As my readers know, I work for a software company (OpenMake Software) that sells a software build and workflow automation product. We have tens of thousands of Java developers using our product through our Eclipse plugin, which gives you true incremental builds that take dependencies into account. You can build, test and do a test deploy all from within Eclipse, and not have to resort to trickery such as injecting partial code into your test server. Since the cost of Meister (which I am not at liberty to publish here) is significantly less per developer than the annual productivity loss calculated above, it makes sense for development managers to move their Java developers away from the wild west of desktop builds, and consider a formal build system. Anything less and you’re ignoring one of your primary missions as a manager: controlling the development process.

Happy Building!

– Matt

Written by Matthew D. Laudato

December 3, 2009 at 8:27 pm