Learn to build Jersey rest client using HttpAuthenticationFeature, which can be used to access REST APIs behind authentication/authorization security. For example, we will create jersey client for services which we secured in Jersey Secured REST APIs tutorial; and I will be extending the sourcecode created for Jersey RESTful client example.
Table of Contents 1. HttpAuthenticationFeature 2. How to secure REST APIs 3. Jersey REST Client Code
1. Jersey Client – HttpAuthenticationFeature
HttpAuthenticationFeature
class provides HttpBasic and Digest client authentication capabilities. The feature work in one of 4 modes i.e. BASIC, BASIC NON-PREEMPTIVE, DIGEST and UNIVERSAL. Let’s quickly learn about them.
- BASIC – It’s preemptive authentication way i.e. information is send always with each HTTP request. This mode must be combined with usage of SSL/TLS as the password is send only BASE64 encoded.
- BASIC NON-PREEMPTIVE – It’s non-preemptive authentication way i.e. auth information is added only when server refuses the request with 401 status code and then the request is repeated with authentication information.
- DIGEST – Http digest authentication. Does not require usage of SSL/TLS.
- UNIVERSAL – Combination of basic and digest authentication in non-preemptive mode i.e. in case of 401 response, an appropriate authentication is used based on the authentication requested as defined in WWW-Authenticate HTTP header.
To use HttpAuthenticationFeature
, build an instance of it and register with client.
1.1. Basic authentication mode
HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic("username", "password"); final Client client = ClientBuilder.newClient(); client.register(feature);
1.2. Basic authentication – non-prempitive mode
HttpAuthenticationFeature feature = HttpAuthenticationFeature.basicBuilder() .nonPreemptive() .credentials("username", "password") .build(); final Client client = ClientBuilder.newClient(); client.register(feature);
1.3. Universal mode
//HttpAuthenticationFeature feature = HttpAuthenticationFeature.universal("username", "password"); //Universal builder having different credentials for different schemes HttpAuthenticationFeature feature = HttpAuthenticationFeature.universalBuilder() .credentialsForBasic("username1", "password1") .credentials("username2", "password2").build(); final Client client = ClientBuilder.newClient(); client.register(feature);
2. How to secure REST APIs
For authentication enabled rest apis, use roles related annotations, such as @RolesAllowed
. For example, this is the code of secured REST API.
@Path("/employees") public class JerseyService { @RolesAllowed("ADMIN") @GET @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public Employees getAllEmployees() { Employees list = new Employees(); list.setEmployeeList(new ArrayList<Employee>()); list.getEmployeeList().add(new Employee(1, "Lokesh Gupta")); list.getEmployeeList().add(new Employee(2, "Alex Kolenchiskey")); list.getEmployeeList().add(new Employee(3, "David Kameron")); return list; } }
Read More : Jersey Secured REST APIs Tutorial
3. Jersey REST Client Code
Below is the jersey rest client basic authentication example which accept username and password details for authentication purpose.
public static void main(String[] args) throws IOException { httpGETCollectionExample(); } private static void httpGETCollectionExample() { ClientConfig clientConfig = new ClientConfig(); HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic("howtodoinjava", "password"); clientConfig.register( feature) ; clientConfig.register(JacksonFeature.class); Client client = ClientBuilder.newClient( clientConfig ); WebTarget webTarget = client.target("http://localhost:8080/JerseyDemos/rest").path("employees"); Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON); Response response = invocationBuilder.get(); System.out.println(response.getStatus()); System.out.println(response.getStatusInfo()); if(response.getStatus() == 200) { Employees employees = response.readEntity(Employees.class); List<Employee> listOfEmployees = employees.getEmployeeList(); System.out.println(Arrays.toString( listOfEmployees.toArray(new Employee[listOfEmployees.size()]) )); } }
3.1. Output with correct username/password
200 OK [Employee [id=1, name=Lokesh Gupta], Employee [id=2, name=Alex Kolenchiskey], Employee [id=3, name=David Kameron]]
3.2. Output with in-correct username/password
401 Unauthorized
Drop me your queries in comments section.
Happy Learning !!
Leave a Reply