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 !!
Thanks for the post , It’s really nice and informative but i have doubt .
How to authenticate a Rest web service with Client “Security Certificate” , PEM File and Pass Pharse using Jersey client or any other client in java.
Thanks in advance 🙂
What are the dependencies used to build the client ?
how ADMIN played role here. I still do not understand. You declare rolesallowed annotation. But how to identify that request from client side is made from particular user/role.
Here, in client side code, ADMIN role is not specified. Please elaborate.
Roles are configured at server side code. You can check here : https://howtodoinjava.com/jersey/jersey-rest-security/
Can I have the jars required to run this code?
Hi ,
I want to fetch data from HPQC URL. When ever I run the code I get following error :
Could you please help me with it
Exception in thread “main” javax.ws.rs.NotAuthorizedException: HTTP 401 No credentials found the request.
at org.glassfish.jersey.client.JerseyInvocation.convertToException(JerseyInvocation.java:1080)
at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:883)
at org.glassfish.jersey.client.JerseyInvocation.lambda$invoke$1(JerseyInvocation.java:767)
at org.glassfish.jersey.internal.Errors.process(Errors.java:316)
at org.glassfish.jersey.internal.Errors.process(Errors.java:298)
at org.glassfish.jersey.internal.Errors.process(Errors.java:229)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:414)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:765)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:428)
at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:324)
at alm.HPQC_Projects.main(HPQC_Projects.java:37)
———————————————————————————————————————————–
public static void main(String args[]){
ClientConfig clientConfig = new ClientConfig();
Client client = ClientBuilder.newClient(clientConfig);
HttpAuthenticationFeature feature = HttpAuthenticationFeature.digest(“XXX”, “XXX”);
client.register(feature);
WebTarget url = client.target(“hpqc_URL”);
String result = url.request().get(String.class);
System.out.println(result);
}
Please can you provide me the dependencies required
I get the below error
The method basic(String, String) is undefined for the type HttpAuthenticator
also below error
The method newClient() is undefined for the type ClientFilter
My code
public class Example {
public static void main(String a[]){
HttpAuthenticator feature = HttpAuthenticator.basic(“username”, “password”);
final Client client = ClientFilter.newClient();
client.register(feature);
}
}
Will i be able to connect in rest 2 APIs using above code
What about the used libraries?
May i know what are the api’s required to run this code ?
How do I handle 401 error and authentication required pop up from server
I am able to do authentication and authorization using provided details, now I want to do some logging for each REST call, i want to fetch the details of the User and log in our system, how can I get user details in my API call.
I am user jersey client 2.4 on gradle build. I am not able to resolve the HttpAuthenticationFeature class. Can anyone please tell the library and import statement for this class.
I am unable to POST java pojo object with authentication using webtarget. Can i get some example code snippet for authentication with POST method?
Hi Lokes,
I want to connect to JIRA using username and password.
I have URL as with username and password.
Please provide a demo code for that
Never tried any client API for Jira.
Have you tried this authentication feature for jenkins?
I have to authenticate with jenkins but it says invocation error.
There is following way to configure the authentication header in Jersey API .
//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);
But not able to figure out how to pass extra parameter to authentication header for e.g. IntegatorKey, SendBehalfOf. those are specific REST service call.
In My Case to call REST service need to pass following parameter as part of authentication header .
1.Username
2. Password
3. IntegatorKey
4. SendBehalfOf
How should I achieve this using the jersey API ?
Let me know if this (your own question on SO) works for you.
Hi,
The example is fine for standalone java application for testing , could you please help to achieve the same for browser based application and how it can be done in both client and server side. Please if you have any example please share us.
I want to know how to get the data from the restfull Api which is digest authenticated in android. Please acknowledge me ASAP waiting for your response.
Thank you
Mukta Bansal
How to call secure rest api from java client? I am getting SSLHandshake Exception. I am using BasicAuth in my code.
By typing url(https) in web browser, Browser prompts for userid and password then its return WADL file.
Please share the code to access these REST API.
Hello Lokesh, can you show an example of the client of that service with PHP or another technology?
Thanks in advance!
I am sorry but I have almost no knowledge of PHP. After a quick google search, pest looks good to me.