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.
Related
Our infra team set up the ca service desk in machine and share the details. I need to make rest call to create the incident from java program. And here i want to use basic authentication by providing the access key. For this I tried to make the end point url to get the access key and after that to create incident as shown below.
http://Host:port/caisd-rest/rest_access
http://CAdeskHost:port/caisd-rest/in
String endpoint = "http://host:port/caisd-rest/rest_access";
HttpClient client = new HttpClient();
String encodedCredentials = new String(Base64.encodeBase64(("username" + ":" + "password").getBytes()));
PostMethod post = new PostMethod(endpoint);
post.addRequestHeader("Accept", "application/xml");
post.addRequestHeader("Content-Type", "application/xml; charset=UTF-8");
post.addRequestHeader("Authorization", "Basic " + encodedCredentials);
post.setRequestBody("<rest_access/>");
try {
System.out.println("Execute Basic Authentication request on " + endpoint);
// Execute request
int result = client.executeMethod(post);
But when I try to execute the above code, getting the 404 error
"The requested resource (/caisd-rest/rest_access) is not available".
Can any one please help me how to find the REST URL for ca service desk whether it is common url for all like /caisd-rest or it is different. Here my infra team just installed the CA service desk. So do we need to do any other steps to provide rest access?
Check in CA Technologies Website, it should be http://<host>:<REST port>/caisd-rest
I had the same issue, problem was that REST wasn't deployed properly, reconfiguring REST Service using this doc: REST API reconfiguration resolved the problem.
I folowed these steps:
Check for existence of NX_ROOT/bopcfg/www/CATALINA_BASE_REST/webapps/caisd-rest. If this directory does NOT exist, that's a very good indication that the REST deploy did not work properly.
Check for the errors in NX_ROOT/log/jrest.log file.
Try fix errors and redeploy REST Service using cmd:
pdm_rest_util -undeploy
pdm_rest_util -deploy
Respected Experts,
I am trying to access a web service that requires basic authentication. I am able to access using the CXF's JaxWsDynamicClientFactory. The code piece for auth looks like:
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient(ID_WSDL);
HTTPConduit conduit= (HTTPConduit) client.getConduit();
AuthorizationPolicy authorization = conduit.getAuthorization();
authorization.setUserName(USERNAME);
authorization.setPassword(PWD);
conduit.setAuthorization(authorization);
However, when I try to use Camel's CXF component to access the same Web Service I get 401 Unauthorized error, since Camel is not sending the authentication information to the Web Service.
My route looks like:
from("file://c:/test?fileName=request.txt&noop=true").routeId("myrouteId")
.process(processor)
.to(cxf)
.to("log:{body}");
In my processor, I am setting the credentials as follows:
Map<String, Object> properties = new HashMap<String, Object>();
AuthorizationPolicy authPolicy = new AuthorizationPolicy();
authPolicy.setAuthorizationType(HttpAuthHeader.AUTH_TYPE_BASIC);
authPolicy.setUserName(USERNAME);
authPolicy.setPassword(PWD);
properties.put("org.apache.cxf.configuration.security.AuthorizationPolicy", authPolicy);
myEndpoint.setProperties(properties);
myEndpoint is CXFEndpoint, retrieved from Exchange.
Am I missing something or something wrong here.
There is a similar question. I had raised my doubt there as a answer since I was not able to comment. However, my answer has been deleted. So, I am raising a fresh question in a hope that I will get some direction to move forward on this.
Thks & brgds
With Willem's help, was able to make this working. The authentication credentials need to passed to the CXF Endpoint in the Route Builder rather than in the Processor. This is as explained by Williem on Camel forum:
If you set the cxfEndpoint property in a processor, it’s a setting of runtime.
As the CxfProducer is created during the camel context start the route, the cxfEndpoint’s property is >not updated.
So, to fix this add the following code to the Route Builder:
Map<String, Object> properties = new HashMap<String, Object>();
AuthorizationPolicy authPolicy = new AuthorizationPolicy();
authPolicy.setAuthorizationType(HttpAuthHeader.AUTH_TYPE_BASIC);
authPolicy.setUserName(USERNAME);
authPolicy.setPassword(PWD);
authPolicy.setAuthorization("true");
//properties.put(AuthorizationPolicy.class.getName(), authPolicy);
properties.put("org.apache.cxf.configuration.security.AuthorizationPolicy", authPolicy);
CxfEndpoint myCxfEp = (CxfEndpoint)getContext().getEndpoint("cxf://");
myCxfEp.setProperties(properties);
Also, version 2.12.3 of Apache Camel is introducing username and password options for basic authentication.
I want to export data from VersionOne into my own Java application. Please help me retrieve this data from it. I used the following code but it is not working.
V1APIConnector dataConnector = new V1APIConnector("http://www10.v1host.com/loxvo/rest-1.v1/", "username", "password");
V1APIConnector metaConnector = new V1APIConnector("http://www10.v1host.com/loxvo/meta.v1/");
metaModel = new MetaModel(metaConnector);
services = new Services(metaModel, dataConnector);
It seems there is some problem from with my URL. Please tell me what will be proper URL here as my company URL is https://www10.v1host.com/loxvo/
You have the correct form of the URL in your post, but not in your sample code. All hosted instances use https as you have shown at the end, but your code has http. While a browser will simply accept a redirect and take you from http to https, the API Client code does not; it simply fails to establish a connection.
I am implementing a TV listing service and I have decided to use ROVI as my data provider.
They provide me with an API that allows me to exchange data between my application and their servers by means of SOAP requests.
Since I am programming in Java, I used wsimport to generate the classes that would enable me to interact with their server.
//Connection
service = new ListingsService();
port = service.getListingsServiceSoap();
I have come across a problem which Google doesn't seem to have the answer for.
According to their API, whenever I want to make a call to a SOAP service I have to add my API Key to the end of url.
The problem is, I don't know how to do that. Using the stubs generated by wsimport, I can create a request object as it should be; however the URL is not displayed as per their specification. The url I currently get is: http://api.rovicorp.com/v9/listingsservice.asmx and what is required is: http://api.rovicorp.com/v9/listingsservice.asmx?apikey=myAPIkey. I obtained that by printing the following code:
System.out.println(port.toString());
Trying to run the following code:
GetServicesRS servicesRS = port.getServices(getServicesRQ, auth)
Yields the following error:
Exception in thread "main" com.sun.xml.internal.ws.client.ClientTransportException: The server sent HTTP status code 403: Forbidden
What java method can I use to append this parameter into the SOAP request URL.
Thanks for your help.
Edit.
I am still struggling with this and haven't been lucky with responses, if anyone could point me in the direction of a framework or something that could facilitate this would be great!
Cheers
I manage to work around my problem using something called BindingProvider.
I added the following to my code:
//Connection
service = new ListingsService();
port = service.getListingsServiceSoap();
BindingProvider bindingProvider = (BindingProvider) port;
bindingProvider.getRequestContext()
.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
"http://api.rovicorp.com/v9/listingsservice.asmx?apikey=" + APIKey);
With the aforementioned code the call to the API is successful:
GetServicesRS servicesRS = port.getServices(getServicesRQ, auth)
Hope it helps someone in the future.
Using code that was generated with wsimport, can the service endpoint be overridden without having to regenerate the code?
I have written a simple java webservice, following are the steps:
I compile the java class and generate a war file
Deploy the war file to my app server (tomcat)
Access the WSDL via the URL e.g. localhost:8080/service/helloservice?wsdl
use the URL with wsimport.bat to generate client classes for example: wsimport http://localhost:8080/service/helloservice?Wsdl
I use those classes in my client app to call the service
The problem is that is the service is deployed on an app server running on port other than 8080, the communication between client and service never happens. I am trying to know what is the best way to create stubs that does not have server and port hardcoded in the stub used by the client.
Your client can set the end-point in the service "port" at runtime via the BindingProvider interface.
Consider the JAX-WS client in this JAX-WS tutorial. Another way to write this code would be:
HelloService service = new HelloService();
Hello port = service.getHelloPort();
BindingProvider bindingProvider = (BindingProvider) port;
bindingProvider.getRequestContext().put(
BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
"http://foo:8086/HelloWhatever");
String response = port.sayHello(name);
Caveat: I haven't downloaded the tutorial code and tested this code against it.
I faced the same issue, and it was terrible coz once the code is moved to production it always looked for the hardcoded WSDL location i.e. Windows C:........etc
I have gone thru various post and pages to find the answer however all was failing then found myself a way by looking at the Service Class generated by JAX-WS imports.
I had to override the JAX-WS WSDL location implementation in my calling class like this.
URL baseUrl;
URL wsdlURL = null;
baseUrl = <your Services>.class.getResource(".");
try {
wsdlURL = new URL(baseUrl, "http://<your path>?wsdl");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
<your Services> yourServices = new <your Services(wsdlURL,new QName("your namespace", "<your service name>"));
System.out.println(Services.getWSDLDocumentLocation());
YourInterface YourInterfacePort = yourServices.getServicePort();
BindingProvider bindingProvider = (BindingProvider)YourInterfacePort;
bindingProvider.getRequestContext().put(
BindingProvider.ENDPOINT_ADDRESS_PROPERTY, url);
YourInterfacePort.methods();