How to secure your REST service? Part 1 – Using BASIC Authentication

In this series of articles, I will be explaining in detail about securing REST services. It includes configuring authentication, authorization and encryption. To begin with, this article talks about setting up BASIC authentication for a simple REST service running on Apache Tomcat.

Authentication is a process of validating the identity of a client who is trying to access the service. There are different authenticating a client, and the simplest protocol is the BASIC authentication over HTTP.

Steps involved in BASIC authentication

(1) Client sends a request without authentication details. e.g.,

Request: curl -D- -X GET localhost:8080/Fig-0.0.1/fig/task/123

(2) Server responds back with error code 401 which denotes unauthorized request. e.g.,

 HTTP/1.1 401 Unauthorized
 Server: Apache-Coyote/1.1
 WWW-Authenticate: Basic realm="jaxrs"
 Content-Type: text/html;charset=utf-8
 Content-Length: 951
 Date: Thu, 05 Dec 2013 00:12:37 GMT

(3) Client sends Base64-encoded username & password in request. e.g.,

curl -D- -H "Authorization: Basic bXl1c2VybmFtZTpteXBhc3Njb2Rl" -X GET localhost:8080/Fig-0.0.1/fig/task/123

(4) Server receives the request, decodes the credentials and compares it with the server version. If the credentials match, then it responds back with status code 200.

 HTTP/1.1 200 OK
 Server: Apache-Coyote/1.1
 Cache-Control: private
 Expires: Wed, 31 Dec 1969 19:00:00 EST
 Content-Type: text/plain
 Content-Length: 325
 Date: Thu, 05 Dec 2013 05:39:46 GMT

Steps to enable BASIC authentication in Apache Tomcat

How to add users, roles and passwords?

Under your tomcat installation, look for $TOMCAT_HOME/conf/tomcat-users.xml file. Add the below lines which defines 2 users and assigns specific roles to them.

<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
   <role rolename="admin"/>
   <role rolename="developer"/>
   <user username="dev1" password="devpassword1" roles="developer"/>
   <user username="admin1" password="adminpassword1" roles="admin"/>
</tomcat-users>

How to enable BASIC authentication in Tomcat?

Now that the users and roles are added, let us activate the authentication in our web application. Open your application’s web.xml and add the following.

  <security-constraint>
    <!-- Specifies the part of the application to be authenticated --> 
    <web-resource-collection>
       <web-resource-name>Secure Task Services</web-resource-name>

       <!-- Denotes which URI patterns needs to be protected. -->
       <url-pattern>/task/*</url-pattern>

       <!-- Only POST, PUT & DELETE calls are authenticated. Omitting http-method tag 
       altogether will secure all access to the url-pattern above -->
       <http-method>POST</http-method>
       <http-method>PUT</http-method>
       <http-method>DELETE</http-method>
    </web-resource-collection>

    <!-- Specifies which roles defined in tomcat-users.xml have access to the resources. -->
    <auth-constraint>
       <role-name>admin</role-name>
    </auth-constraint>

    <!-- Requests are processed without encryption -->
    <user-data-constraint>
       <transport-guarantee>NONE</transport-guarantee>
    </user-data-constraint>
 </security-constraint>

 <!-- Denotes the authentication method, which in our case is BASIC -->
 <login-config>
    <auth-method>BASIC</auth-method>
 </login-config>

That’s about it. If you bounce the Tomcat and try to access the resources via POST/PUT/DELETE method, you will be access for credentials.

Advantages of BASIC authentication: Very easy to set up authentication.
Disadvantages of BASIC authentication: Username/password can be easily sniffed out by attackers since it is just encoded, and not encrypted.

Encrypted HTTP Request

Using an encrypted HTTP connection like HTTPS where packets are encrypted with SSL solves the downside of BASIC authentication. To enable HTTPS, uncomment the below lines in $TOMCAT_HOME/conf/server.xml .

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
 maxThreads="150" scheme="https" secure="true"
 clientAuth="false" sslProtocol="TLS" />

and change the <transport-guanrantee> value in web.xml to CONFIDENTIAL instead of NONE.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s