In previous post, I explained basic
authentication using simple servlet filter. In this post, I am going to explain
authenticating user using ContainerRequestFilter.
Define
custom filter by implementing ContainerRequestFilter interface
First we need to define custom filter by
implementing ‘javax.ws.rs.container.ContainerRequestFilter’ interface. All the
container request filters must implement ContainerRequestFilter class. Request
filter is executed before the resource method is run and before the response is
created.
We must annotate the filter class that
implements ContainerRequestFilte interface with @Provider annotation, so that
the JAX-RS runtime will discover this filter.
Categories
of filters
There are two variant of filters.
a. Pre-matching filters
b. post-matching filters
Pre-matching
filters
Pre-matching filters execute before the
request matching is started. Request matching is the process of identifying a
resource method for given request. Annotate a filter class with @PreMatching
annotation to make it as Pre-matching filter.
post-matching
filters
post-matching filters applied after a resource method has been selected to
process the request (after request matching happens). Since these filter are
applied after matching a resource method, these won't impact resource method
matching process. By default all filters are post-matching filters.
Following step-by-step
procedure explains complete working application.
Step 1: Create new dynamic web project ‘jersey_authentication’
in eclipse.
File ->
New -> Dynamic Web Project
Give the
project name as ‘jersey_authentication’, Press Next.
Select the
check box ‘Generate web.xml deployment descriptor’, press Finish.
Step 2: Convert this project to maven project.
Right click
on the project -> Configure -> Convert to Maven Project.
Total
project structure looks like below.
Step 3: Update web.xml like below.
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>jersey_authentication</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>Jersey REST Service</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>jersey.config.server.provider.packages</param-name> <param-value>com.self_learn</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Jersey REST Service</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> </web-app>
Step 4: Update pom.xml for dependencies.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>jersey_authentication</groupId> <artifactId>jersey_authentication</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <build> <sourceDirectory>src</sourceDirectory> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>2.4</version> <configuration> <warSourceDirectory>WebContent</warSourceDirectory> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.glassfish.jersey.containers</groupId> <artifactId>jersey-container-servlet-core</artifactId> <version>2.21</version> </dependency> <dependency> <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-server</artifactId> <version>2.21</version> </dependency> </dependencies> </project>
Step 5: Create a package com.self_learn.filter, define
class AuthFilter.
package com.self_learn.filter; import java.io.IOException; import javax.ws.rs.WebApplicationException; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.core.Response.Status; import javax.ws.rs.ext.Provider; @Provider public class AuthFilter implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext requestContext) throws IOException { String username = requestContext.getHeaderString("username"); String password = requestContext.getHeaderString("password"); if (!("admin".equals(username) && "admin".equals(password))) { throw new WebApplicationException(Status.UNAUTHORIZED); } } }
‘filter’
method verifies the headers for 'username', 'password'. If both the headers has
value 'admin', then request succeed, else client get response status '401
Unauthorized'
Step 6: Create a package 'com.self_learn.resource', define
class HelloWorld.
package com.self_learn.resource; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @Path("/hello") public class HelloWorld { @GET @Produces(MediaType.TEXT_PLAIN) public String message() { return "Hello World !"; } }
Complete
project structure looke like below.
Run the
application on server. To demonstrate this application, I am going to use ‘Advanced
Rest client’ plugin of Chrome browser.
Open
Advanced Rest client and use following url.
Set
following headers.
username:
admin
password:
admin
Submit the
request by setting above headers, you will get following kind of response.
Submit the
request by setting wrong headers, you will get following kind of response.
No comments:
Post a Comment