Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

OAuth2 Authentication in Zerocode

DZone's Guide to

OAuth2 Authentication in Zerocode

Want to learn more about how you can implement OAuth2 authentication in your code?

· Security Zone ·
Free Resource

Discover how to provide active runtime protection for your web applications from known and unknown vulnerabilities including Remote Code Execution Attacks.

Zerocode is an open-source library that enables API testing via simple declarative JSON steps — REST, SOAP, and DB services. This article is about using zerocode to test a REST API that supports OAuth2 authentication.

Why Zerocode?

Testing the REST API is still a bit of a pain with modern tools like Insomnia, Postman, REST Assured, etc. Zerocode has taken a different approach to solving the fuss around REST API testing. Testing here refers to automation testing. When using zerocode, your REST API automation testing becomes more elegant and straightforward. It is also more maintainable and easy to use.

You just need to manually test your REST API once, which can be recorded and ran whenever by whoever wants to test the integrity of the REST API. It can also be run from CI jobs.

For more information, check out this page on GitHub.

GitHub page

OAuth2

Overview

OAuth2 is a popular HTTP authentication mechanism widely supported these days. It is not static, unlike the auth token. It is also considered to be more secure than other authentication methods. There are two models where one is the online flow and the other is offline flow. For the online flow, the user needs to provide consent every time. Whereas for the offline flow, once the user gives the consent, a refresh token will be generated, which is non-expiring. The obtained refresh token can be used to generate access tokens until the user revokes the refresh token.

OAuth2 in Zerocode

If you have a REST API that needs to be testing, but your REST API only supports OAuth2 authentication and you want to test it in the same way, it makes sense to test the API as it is in production so that it behaves similarly when testing. Also, unlike other authentication methods, OAuth2 is dynamic. The tokens are valid only for a certain amount of time. So, it cannot be hard-coded; instead, it has to be dynamically generated.

There is no built-in support for OAuth2 authentication in zerocode. But we are going to exploit the extendability of the zerocode to support OAuth2 authentication. Zerocode can be extended to satisfy almost all of your requirements.

It is possible to inject a custom (Authorization) header in every request by extending theBasicHttpClient and overriding thehandleHeadersmethod. In this method, you can insert anything of your choice.

package org.jsmart.zerocode.zerocode.oauth2;

import java.util.Map;
import java.util.Timer;

import org.jsmart.zerocode.core.httpclient.BasicHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.Inject;
import com.google.inject.name.Named;

import org.apache.http.client.methods.RequestBuilder;

/**
 * @author santhoshTpixler
 *
 */

/*
 * Note: This implementation supports the OAuth2.0 with refresh_token
 * 
 * Reference: https://tools.ietf.org/html/rfc6749#page-11
 * 
 * 
 *  1. The refresh_token, access_token URL, client_id and client_secret
 *  should be generated by the user and stored in the properties file 
 *  mentioned in the @TargetEnv("host.properties").
 *  2. For generating the refresh token REST Client such as Insomnia (https://insomnia.rest/) can 
 *  be used. 
 *  
 *  Note: Postman cannot be used as it does not show the refresh token.
 */
public class OAuth2HttpClient extends BasicHttpClient {

	private static final Logger LOGGER = LoggerFactory.getLogger(OAuth2HttpClient.class);

	/*
 * Properties to be fetched from the host.properties
 */
	private static final String CLIENT_ID = "client_id";
	private static final String CLIENT_SECRET = "client_secret";
	private static final String REFRESH_TOKEN = "refresh_token";
	private static final String ACCOUNTS_URL = "accounts_url";

	/*
 * If the Authorization header contains the replacement value as specified by the 
 * below constant, then it is replaced with the valid access token
 */
	private static final String ACCESS_TOKEN_REPLACEMENT_VALUE = "DIY";
	/*
 * Time interval in which the accessToken should be renewed
 */
	private static final long REFRESH_INTERVAL = 3540000;

	private OAuth2Impl oauth2 = null;

	@Inject
	public OAuth2HttpClient(@Named(CLIENT_ID) String clientId, @Named(CLIENT_SECRET) String clientSecret, @Named(REFRESH_TOKEN) String refreshToken, @Named(ACCOUNTS_URL) String accountsURL) {
		this.oauth2 = new OAuth2Impl(clientId, clientSecret, refreshToken, accountsURL);
		Timer timer = new Timer();
		timer.schedule(oauth2, 0, REFRESH_INTERVAL);
		synchronized(oauth2) {
			try {
				oauth2.wait();
			} catch(InterruptedException e) {
				Thread.currentThread().interrupt();
			}
		}
	}

	@Override
	public RequestBuilder handleHeaders(Map < String, Object > headers, RequestBuilder requestBuilder) {
		String authorization = (String) headers.get("Authorization");
		if (authorization != null && authorization.equals(ACCESS_TOKEN_REPLACEMENT_VALUE)) {
			headers.put("Authorization", oauth2.getAccessToken());
			LOGGER.info("Token injected into header.");
		}
		return super.handleHeaders(headers, requestBuilder);
	}
}


Conclusion

All you need is to implement the OAuth2 authentication logic in your code. Finally, generate the token from your implementation and inject it into the request header. Sound cool? But what about the OAuth2 implementation?!

We've got you covered. There is a working example available in the hello-world-repo. You can copy it and flavor it according to your needs. 

No library can support all your requirements, but it should be extendable to achieve it. Zerocode was written with this as a basic principle.

Find out how Waratek’s award-winning application security platform can improve the security of your new and legacy applications and platforms with no false positives, code changes or slowing your application.

Topics:
rest api testing ,api testing ,zeroode ,security ,oauth2 ,authenticaiton ,tutorial ,oauth2 tutorial ,token

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}