5 Tips for Building your Java API
Developers use APIs to for everything! You build APIs for your own apps to consume, or as a part of a microservices architecture. Bottom line, you’re building and using APIs to make your life easier. The ongoing effort to simplify development and work more efficiently, sometimes this also means looking for new libraries or processes (or more often less process). For many teams managing authentication and access control for their apps and APIs is more work than it’s worth, or simply not an efficient use of time, so we want to share a few tips that will save you time and code, along with making your applications more secure and easier to maintain.
For a bit of context: Okta at its core, is a Java-based REST+JSON API, built on the Spring Framework. We store user credentials and data on behalf of other companies, so for us security is paramount. Thus, my first requirement for these tips is that they help manage access to your Java API securely.
These tips should be universal to any type of Java application. They will help you move faster, write less code, and at the same time be more secure: a trifecta!
1. Don’t roll your own security
Seriously, just don’t, it’s hard.
Almost everyone knows to avoid implementing their own cryptography. The rest of your security stack is no different, and the risk/reward just isn’t worth it. There’s a high chance you’ll make some sort of mistake. Since 1999 there have been 89373 CVEs (Common Vulnerabilities and Exposures). And that’s just what’s been made public, many of those by very smart people.
You may think that dealing with a simple use case like validating a user’s password is trivial, all you’re doing is just comparing a couple strings after all. You would be wrong. You need to validate the password’s hash, audit the attempt, mitigate against dictionary attacks, and that’s just the tip of the iceberg. Your best bet is to use an existing library or a framework like Apache Shiro or Spring Security and let the framework handle the complexities!
2. Use TLS, always!
It’s 2017, everything should be HTTPS now, even the sites on your company’s intranet. Let’s encrypt makes this free and easy, which means you can stop using insecure self-signed keys too! You can even set up a local Tomcat or Nginx instance with a certificate.
Making your application require TLS (HTTPS/SSL) is usually a one liner, so everybody should be doing it!
For Apache Shiro, it is just property:
[urls]
/** = ssl
And Spring Security, a single method call when configuring an HttpSecurity:
http.requiresChannel()
.anyRequest().requiresSecure();
Or just use a few properties with Spring Boot:
server.port=8443
server.ssl.key-store=classpath:keystore.jks
server.ssl.key-store-password=secret
server.ssl.key-password=another-secret
3. Build your Java web service with Spring Boot
Spring Boot is an opinionated view of the Spring platform which makes it dead simple to write twelve-factor apps in very few lines. If you’re still building WAR files you owe it to yourself to check this out. You can create complicated, application wide functions like setting up an OAuth resource server by using a single annotation (@EnableResourceServer
) or change the server’s port with a single property:
server.port = 8090
If Spring is not your bag, take a look at Dropwizard for an opinionated JAX-RS stack.
4. Use monitoring and metrics to watch your back
It’s pretty difficult to pinpoint errors without any data. Spring Boot makes gathering metrics easy with Actuator, just add a single dependency to your application.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Then browse to /health
or /metrics
to view health checks or application metrics respectively. Dropwizard does the same thing with /healthcheck
and /metrics
.
Here’s an output from a Spring Boot application’s /metrics
endpoint, out of the box:
{
"classes": 7704,
"classes.loaded": 7704,
"classes.unloaded": 0,
"counter.status.200.metrics": 1,
"gauge.response.metrics": 99.0,
"gc.ps_marksweep.count": 2,
"gc.ps_marksweep.time": 272,
"gc.ps_scavenge.count": 8,
"gc.ps_scavenge.time": 136,
"heap": 3728384,
"heap.committed": 470016,
"heap.init": 262144,
"heap.used": 207793,
"httpsessions.active": 0,
"httpsessions.max": -1,
"instance.uptime": 25020,
"mem": 529086,
"mem.free": 262222,
"nonheap": 0,
"nonheap.committed": 60608,
"nonheap.init": 2496,
"nonheap.used": 59067,
"processors": 8,
"systemload.average": 5.56103515625,
"threads": 24,
"threads.daemon": 22,
"threads.peak": 28,
"threads.totalStarted": 32,
"uptime": 37182
}
5. Protect your sensitive bits
People treat API keys insecurely, it’s a fact of life. Keys get emailed around or checked into source control. Maybe this is because they seem more opaque than a password, I don’t know, but they’re just as sensitive, if not more so. If you need to store your API keys in a file, make sure there is limited access to that file. For example, we recommend storing our Okta yaml file in private directory ~/.okta/okta.yaml
and setting the file permissions to allow only the owner to read:
$ chmod u=r,go-rwx ~/.okta/okta.yaml
If you are creating API keys for users of your applications, plan to warn them. SSH ignores files in your ~/.ssh
directory if the permissions are not set correctly. GitHub does a great job of warning users by marking items in the UI with ‘Danger Zone’ marking.
Bonus: Write less code, give Okta a try!
Java has a bit of a reputation (and rightly so) for being verbose. All of the examples above show you how to write less code and when possible take advantage of existing libraries so you can focus on the code that will drive your business.
Shameless plug time: You can also write less code by integrating Okta for fully featured user management. Just connect your apps, choose an IdP (or use ours), add users, configure rules, customize your login page, and then gain insights from our built-in reports. Want to see Okta in action? Check out these tutorials:
- Build a Secure Notes Application with Kotlin, TypeScript, and Okta
- Secure a Spring Microservices Architecture with Spring Security, JWTs, Juiser, and Okta
- What is OpenId Connect
And, as always, if you have any questions or comments you can hit me up on Twitter @briandemers, or follow our whole team @oktadev.
Okta Developer Blog Comment Policy
We welcome relevant and respectful comments. Off-topic comments may be removed.