Authentication problem using Jersey and Glassfish - java

I'm trying to configure Glassfish using the REST interface. I am using Jersey in my Java code. All works well, except authenticating. Bellow is a peace of code i use to do a GET. Whenever i have a used defined in Glassfish, this peace of code returns 401. I have checked the credentials using Glassfish Administration Console and CURL and they are valid. I suppose it is a problem in the way i am using Jersey. I have googled this, but i can not find relevant information. Does anyone have any suggestions? Thanks
Client client;
public JerseyRESTClient() {
client = Client.create();
client.addFilter(new HTTPBasicAuthFilter("user1", "a"));
}
public String GET(String url, String format) throws IOException {
WebResource webResource = client.resource(url);
ClientResponse c = webResource.accept(format).get(ClientResponse.class);
return new Integer(c.getStatus()).toString() + System.getProperty("line.separator") + c.getEntity(String.class);
}

Related

JIRA REST API - 415 Unsupported Media Type error in ClientResponse

I am trying to send a POST request via a WebResource instance using a Jersey Client. But no matter how i specify the request headers or types, it will give me a 415 Unsupported Media Type error. Below is my code
String SERVICE_URL = "http://hostIpAddress:8080/JiraUpdate/rest/createin/jira/createticket?"; // hostIpaddress is our server ip
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
System.out.println("SERVICE_URL=" + SERVICE_URL);
WebResource webResource = client.resource(UriBuilder.fromUri(SERVICE_URL).build());
String input = "{\"fields\":{\"project\":{\"key\":\"Invoicing\"},\"summary\":\"REST Test\",\"description\": \"Creating of an issue using project keys and issue type names using the REST API\",\"issuetype\":{\"name\":\"Bug\"}}}";
ClientResponse response = webResource.header("Content-Type", "application/json;charset=UTF-8")
.type(MediaType.TEXT_PLAIN_TYPE).post(ClientResponse.class, input);
I have tried to set the type to MediaType.APPLICATION_FORM_URLENCODED_TYPE as well as MediaType.APPLICATION_JSON but it doesnt change the response. I am running this code as a standalone executable JAR in a linux environment. Any help is appreciated.
Based on Vijay-Bhushan example in the linked SO article mentioned in my second comment your code should be (and he noted UTF-8 wasnt needed):
String SERVICE_URL = "http://hostIpAddress:8080/JiraUpdate/rest/createin/jira/createticket?"; // hostIpaddress is our server ip
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
System.out.println("SERVICE_URL=" + SERVICE_URL);
WebResource webResource = client.resource(UriBuilder.fromUri(SERVICE_URL).build());
String input = "{\"fields\":{\"project\":{\"key\":\"Invoicing\"},\"summary\":\"REST Test\",\"description\": \"Creating of an issue using project keys and issue type names using the REST API\",\"issuetype\":{\"name\":\"Bug\"}}}";
ClientResponse response = webResource.header("Content-Type","application/json;charset=UTF-8").post(ClientResponse.class,input);
The Jersey Client API documentation has some great examples.

How can i call one webservice from another webservice and return the result

I am new to writing rest services. I have written a webservice to query mysql db and return data as JSON.Using jersey 1.9, war file is hosted on tomcat 7 and MySql db.
There is an existing webservice written and maintained by third party where i need to post this data.
I would like to know if it is possible to call WebService-2 from WebService-1 and return the response of Webservice-2 through WebService-1.
I would like to note that Webservice-2 cannot be altered. It currently takes JSONObject by POST and returns another JSONObject as the response.
I hope you are looking for this API Example:
Client client = Client.create();
WebResource webResource = client.resource("<some_address>/<resource>");
ClientResponse response = webResource.accept("application/json").get(ClientResponse.class);
//modify the response
//return the value
You can do it through jersey API.

CXF + wsdl2java + authentication

I created the jar from the WSDL for my client using the wsdl2java command. Now, I need to know how I can authenticate my client in order to complete an operation?
I am using CXF 2.7.16. I created my service using the generated class MyApp_Service, I am struggling with this. Isn't there a simple way to tell my client the credentials it should use to gain access to the web service?
I read about the Spring configuration, however I am unable to figure out if it applies to my case and how if yes. I tried to cast the MyApp_Service class to BindingProvider in order to use the method which consist to put the USERNAME and PASSWORD properties in the context with a value. However, MyApp_Service cannot be cast to BindingProvider.
This is my first web service client application ever. So, any help will be welcomed.
Update 2015-05-28: I tried to define the AuthenticationPolicy but is seems not working. Here is the code:
Client client = JaxWsDynamicClientFactory.newInstance().createClient(wsdlUrl);
ClientImpl clt = (ClientImpl) client;
HTTPConduit cc = (HTTPConduit) clt.getConduit();
org.apache.cxf.configuration.security.ObjectFactory secOF = new org.apache.cxf.configuration.security.ObjectFactory();
AuthorizationPolicy ap = secOF.createAuthorizationPolicy();
ap.setUserName(usagerWS);
ap.setPassword(mdpWS);
ap.setAuthorizationType("Basic");
cc.setAuthorization(ap);
Sniffing with WireShark, the Authorization header is clearly missing in the HTTP request.
What is missing?
Problem solved, here is the solution:
MyApp_Service service = new MyApp_Service(wsdlUrl, new QName(namespace, serviceName));
MyApp port = service.getMyApp();
// Set credentials
Map<String, Object> reqCtxt = ((javax.xml.ws.BindingProvider) port).getRequestContext();
reqCtxt.put(javax.xml.ws.BindingProvider.USERNAME_PROPERTY, username);
reqCtxt.put(javax.xml.ws.BindingProvider.PASSWORD_PROPERTY, password);
No more usage of the dynamic client. Only the classes generated with wsdl2java are used.

Sending POST data to REST service with authentication

I want to send JSON data to a REST service which includes authentication, but when I try to run this code, it throws a RuntimeException and HTTP code 302. But the link is working fine through a REST client. I think my code is unable to provide the authentication details to the link.
I have tried so many combinations, but it's still not working. Can anyone suggest where I am going wrong?
JSONObject obj=new JSONObject(req); //JSON Object
ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING,
Boolean.TRUE);
Client client = Client.create(clientConfig);
//Authentication filter
client.addFilter(new HTTPBasicAuthFilter("username", "password"));
WebResource webResource = client.resource(
"http://licruleswb-dev.cloudapps.cisco.com/LicenseRules/rest/invokeRule");
ClientResponse response = webResource.accept("application/json").type(
MediaType.APPLICATION_JSON_TYPE).post(ClientResponse.class, obj.toString());
if (response.getStatus() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + response.getStatus());
}
This is the error:
ERROR:Exception in thread "main" java.lang.RuntimeException: Failed :
HTTP error code : 302
at Test2.main(Test2.java:64)
Test2 is my class.
What framework are you using? Jersey? You can try setting the basic auth with:
Authenticator.setDefault(new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("username", "password".toCharArray());
}
});
It seems that you use Jersey REST client. You need to be aware that this approach is deprecated in version 2.5 and removed in version 2.6. In higher versions of Jersey, you need to use this:
// Send with all calls
HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic(
"username", "password");
or
// Send with a single call
Response response = client.target("http://...").request()
.property(HTTP_AUTHENTICATION_BASIC_USERNAME, "username")
.property(HTTP_AUTHENTICATION_BASIC_PASSWORD, "password").get();
See this link for more details: https://jersey.java.net/documentation/latest/client.html#d0e5181.
You could enable traces in your application or use an external HTTP proxy (like tcpmon) to see the actual sent request (if there is a header Authorization with content).
Hope it helps you,
Thierry

Jersey/JAX-RS Client throwing 400 Bad Request

I have a RESTful Java web service that I built using Jersey. The client for it defines a resource with the following method:
#Override
public String saveWidget(Widget widget) {
return webResource.path("user").type(MediaType.APPLICATION_JSON).entity(widget).post(String.class, Widget.class);
}
Then, a driver using this client:
public class Driver {
public static void main(String[] args) {
WidgetClient client;
WidgetClientBuilder builder = new WidgetClientBuilder();
client = builder.withUri("http://localhost:8080/myapi").build();
Widget w = getSomehow();
String widgetUri = client.getWidgetResource().saveWidget(w);
System.out.println("Widget was saved URI was returned: " + widgetUri);
}
}
When I run this I get:
Exception in thread "main" com.sun.jersey.api.client.UniformInterfaceException: POST http://localhost:8080/myapi/widget returned a response status of 400 Bad Request
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:688)
at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
at com.sun.jersey.api.client.WebResource$Builder.post(WebResource.java:570)
at com.my.myapi.WidgetResource.saveWidget(WidgetResource.java:27)
at com.my.myapi.Driver.main(Driver.java:32)
I know the service endpoint is valid because I can hit it from another (non-Java) web client without issues. This means that either my Widget instance is malformed or that there is something with my Java client method (saveWidget). I ruled out my w Widget being bad by serializing it into JSON, and then copying it into my non-Java web client and POSTing to the same endpoint (no issues arose). So this tells me I have the client method configured wrong. Any ideas?
This is regarding making a call POST call using Jersey client.
For jersey client, default client configuration uses ChunkedEncoding and gzip. This can be checked in request headers for POST call. Content length of payload (JSON String or any object mapper pojo) and request headers received by post call i.e. header name CONTENT-LENGTH, CONTENT-ENCODING. If there is difference, POST call might return 400 bad request. (Something like unable to process JSON). To solve this, you can disable ChunkedEncoding, gzip encoding. Code snippet for the same:
clientConfiguration.setChunkedEncodingEnabled(false);
clientConfiguration.setGzipEnabled(false);
Client client = (new JerseyClientBuilder(environment)).using(clientConfiguration).using(environment).build("HTTP_CLIENT");
WebTarget webTarget = client.target(endpoint);
Response response = webTarget.path(path).request(MediaType.APPLICATION_JSON).post(Entity.json(jsonString));
.post(String.class, Widget.class);
You appear to be posting a Class object, not a Widget object.

Categories

Resources