Change ejb3 webservice url in weblogic - web-services

I have an EJB3 session bean annotated with #WebService(serviceName="MyServiceName", portName="MyPortName"). When it is deployed into Weblogic 11g the service endpoint is located at
host:port/BeanClassName/MyServiceName
Is it possible to change the service endpoint address of the webservice? i.e. to
host:port/my/context/root/something/MyServiceName
I tried to use the weblogic-webservices.xml deployment descriptor, but it requires the webservices.xml descriptor which requires a WSDL location element, but that should be generated by the server and the location of it differs in the dev and prod environments.

Suppose you have an EJB
package com.example;
#Stateless
#WebService
OrganizationService {...}
First you should write a webservices.xml file for it as follows, since its sections will be referenced back from weblogic-webservices.xml where the actual endpoint configuration is done.
webservices.xml (Caution: by adding webservices.xml webservice annotations in classes are overridden!):
<?xml version="1.0" encoding="UTF-8"?>
<webservices xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2">
<webservice-description>
<!-- just a label, can be anything you want -->
<webservice-description-name>MyServiceName</webservice-description-name>
<port-component>
<!-- just a label, can be anything you want -->
<port-component-name>MyServicePort</port-component-name>
<!-- Target namespace from wsdl -->
<wsdl-port xmlns:ex="http://example.com/target/name/Space">ex:MyService</wsdl-port>
<!-- Fully qualified class name of the ejb interface/bean providing the service -->
<service-endpoint-interface>com.example.OrganizationService</service-endpoint-interface>
<service-impl-bean>
<!-- The class name of the bean providing the service -->
<ejb-link>OrganizationService</ejb-link>
</service-impl-bean>
</port-component>
</webservice-description>
</webservices>
Then in the weblogic-webservices.xml you can define whatever endpoint you want.
weblogic-webservices.xml:
<?xml version='1.0' encoding='UTF-8'?>
<weblogic-webservices xmlns="http://www.bea.com/ns/weblogic/weblogic-webservices" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-webservices http://www.bea.com/ns/weblogic/weblogic-webservices/1.0/weblogic-webservices.xsd">
<webservice-description>
<!-- This must match the name given in webservices.xml -->
<webservice-description-name>MyServiceName</webservice-description-name>
<webservice-type>JAXWS</webservice-type>
<port-component>
<!-- This must match the name given in webservices.xml -->
<port-component-name>MyServicePort</port-component-name>
<service-endpoint-address>
<webservice-contextpath>/myContextPath</webservice-contextpath>
<webservice-serviceuri>/myServiceURI</webservice-serviceuri>
</service-endpoint-address>
</port-component>
</webservice-description>
</weblogic-webservices>

I found a solution that adds another endpoint to the one generated from a JAX-WS web service by WebLogic.
I have a web service like this (simplified):
#WebService(name = "ClientService",
portName = "ClientService",
serviceName = "ClientService")
public class ClientWebService {
#WebMethod
public ExtClient findClientDetails(String ref) {
// etc.
}
}
The WebLogic endpoint is <context>/ClientService but I want it to be <context>/client/01.
In web.xml I have:
<listener>
<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>
<servlet>
<servlet-name>WebServiceServlet</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>WebServiceServlet</servlet-name>
<url-pattern>/client/01</url-pattern>
</servlet-mapping>
Now WebLogic offers the web service at both endpoints.
Specifying the URI in web.xml is needed because the JAX-WS library in WebLogic ignores endpoint specifications in sun-jaxws.xml. (In contrast, GlassFish only exposes enpoints that are specified in sun-jaxws.xml.)

Related

Including a CDATA field in a Service Connector

An API I am communicating with is Soap based and requires XML with inner XML (CDATA) in the request.
For the service connector action test I have hard-coded the inner xml with this format:
<![CDATA[
<Application xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ApplicationCrossReferenceId="123">
...
...
</Application> ]]>
where the dots indicate the data contained.
When running the test the request payload has been transformed to the html entity for < which is $lt; - as seen below :
Is there a way to avoid this?
This is a bug in Informatica. the other characters are decoded back to their original correctly, as described in KB 512858, &gt and &lt however are not decoded.
A bug report has been raised 29.05.2020.
Edit: Further investigation revealed that using CDATA was not necessary in my case, instead I was able to use the following input for the body binding:
<Application xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ApplicationCrossReferenceId="123">
...
...
</Application>

404 when using Tuckey URLRewriteFilter with JAX-RS

I'm trying to use the URLRewriteFilter in combination with a number of different types of resources. It works perfectly fine for static resources and regular servlets. For JAX-RS-based services however, I get a 404.
This is the situation:
There are two web applications:
base
base#nested
Requests for /base/Something/nested/furtherPath need to be forwarded to /base/nested/furtherPath. This implies forwarding from the /base context to the /base/nested context.
To do that, I configured the URLRewrite filter on the /base context:
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter
</filter-class>
<init-param>
<param-name>logLevel</param-name>
<param-value>DEBUG</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
The rules (urlrewrite.xml) are as follows:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN"
"http://www.tuckey.org/res/dtds/urlrewrite4.0.dtd">
<urlrewrite use-context="true">
<rule>
<from>/base/([^/]*)/([^/]*)/(.*)</from>
<to type="forward" context="base/nested">/$3</to>
</rule>
</urlrewrite>
The crossContext attribute of the /base context is set to true.
This works perfectly fine for regular servlets and static resources but not for JAX-RS services. I'm doing this in TomEE JAX-RS 1.6.0.
Your help is appreciated!

Spring Security with REST web services - cannot authenticate via header when testing with Curl

I'm new to Spring and spring security and I can't seem to get this working. I'm securing a web service with Spring security. I'm getting the appropriate responses back - 401, 200, etc - for the secure requests and when I explicitely login to the URL I defined. However, when I try to test the actual url providing data via curl or poster sending the authentication in the header, I can't get it to work.
Here's my servlet-security.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<http create-session="stateless" entry-point-ref="restAuthenticationEntryPoint">
<intercept-url pattern="/services/schedule/**" access="ROLE_USER, ROLE_ADMIN"/>
<custom-filter ref="myFilter" position="FORM_LOGIN_FILTER"/>
<!-- Adds a logout filter to Spring Security filter chain -->
<logout logout-url="/api/logout" delete-cookies="true" invalidate-session="true"
success-handler-ref="restLogoutSuccessHandler"/>
</http>
<beans:bean id="myFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager"/>
<beans:property name="authenticationSuccessHandler" ref="mySuccessHandler"/>
<beans:property name="filterProcessesUrl" value="/api/login"/>
<beans:property name="usernameParameter" value="username"/>
<beans:property name="passwordParameter" value="password"/>
<beans:property name="postOnly" value="true"/>
</beans:bean>
<!-- Configures a custom authentication success handler that returns HTTP status code 200 -->
<beans:bean id="mySuccessHandler" class="com.touchvision.pilot.security.RestAuthenticationSuccessHandler"/>
<!-- Configures a custom authentication failure handler that returns HTTP status code 401 -->
<beans:bean id="restAuthenticationFailureHandler" class="com.touchvision.pilot.security.RestAuthenticationFailureHandler"/>
<!-- Configures a custom logout success handler that returns HTTP status code 200 -->
<beans:bean id="restLogoutSuccessHandler" class="com.touchvision.pilot.security.RestLogoutSuccessHandler"/>
<!-- Declare an authentication-manager to use a custom userDetailsService -->
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="customUserDetailsService">
<password-encoder ref="passwordEncoder"/>
</authentication-provider>
</authentication-manager>
<!-- Use a Md5 encoder since the user's passwords are stored as Md5 in the database -->
<beans:bean class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" id="passwordEncoder"/>
<!-- A custom service where Spring will retrieve users and their corresponding access levels -->
<beans:bean id="customUserDetailsService" class="com.touchvision.pilot.services.CustomUserDetailsService"/>
</beans:beans>
As I said, I can login fine via posting the creds to the /api/login. However, when I try to send the authentication in the header with an actual data request, I get an error that says "This request requires HTTP authentication." The curl command I'm using is:
curl -u admin#touchvision.com:admin123 "http://local.touchvision.com/services/schedule/list"
Thanks for any and all help.
You only have a form-login filter (UsernamePasswordAuthenticationFilter) configured that processes form parameters passed in a HTTP POST request, but there is nothing on the server side that would process the header of a request.
Try configuring a BasicAuthenticationFilter that will authenticate requests based on info passed in the header.
Have you tried using %40 intead of the # sign in the user ID. Also, depending on your version of CURL, you may want to try quotes around the entire -u parameter.

Adding authorization to a third-party web service

I have several third-party web services of which I only have their WSDL's. Currently they are only accessible in my internal network. I would like to expose those web services to the internet but, since they read/write sensitive information, I would need some sort of authentication mechanism in order to assure that only certain users are able to invoke them.
The idea is to expose exactly the same interface (same operations with the same parameters) but intercepting each invocation to check the security and then invoking the original web service if the authentication is valid or returning an exception or error message otherwise. I've been trying to use Mule ESB for the task abut I can't quite get there
Is this possible with mule? If not, how would i go about doing this? Can anyone point me in the right direction?
Thanks in advance.
Here is an example of a web service proxy adding WS-Security to an unsecure target web service:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:http="http://www.mulesoft.org/schema/mule/http"
xmlns:cxf="http://www.mulesoft.org/schema/mule/cxf"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:mule-ss="http://www.mulesoft.org/schema/mule/spring-security"
xmlns:ss="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/3.2/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/3.2/mule-http.xsd
http://www.mulesoft.org/schema/mule/cxf http://www.mulesoft.org/schema/mule/cxf/3.2/mule-cxf.xsd
http://www.mulesoft.org/schema/mule/spring-security http://www.mulesoft.org/schema/mule/spring-security/3.2/mule-spring-security.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<mule-ss:security-manager>
<mule-ss:delegate-security-provider
name="memory-provider" delegate-ref="authenticationManager" />
</mule-ss:security-manager>
<spring:beans>
<ss:authentication-manager alias="authenticationManager">
<ss:authentication-provider>
<ss:user-service id="userService">
<ss:user name="user" password="pass" authorities="ROLE_USER" />
</ss:user-service>
</ss:authentication-provider>
</ss:authentication-manager>
<cxf:security-manager-callback id="serverCallback" />
</spring:beans>
<flow name="secureStockQuoteWsProxy">
<http:inbound-endpoint address="http://localhost:8080/sec-ws/stockquote"
exchange-pattern="request-response">
<cxf:proxy-service>
<cxf:inInterceptors>
<spring:bean
class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />
<spring:bean
class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<spring:constructor-arg>
<spring:map>
<spring:entry key="action" value="UsernameToken" />
<spring:entry key="passwordCallbackRef"
value-ref="serverCallback" />
</spring:map>
</spring:constructor-arg>
</spring:bean>
</cxf:inInterceptors>
</cxf:proxy-service>
</http:inbound-endpoint>
<http:outbound-endpoint address="http://www.webservicex.net/stockquote.asmx"
exchange-pattern="request-response">
<cxf:proxy-client enableMuleSoapHeaders="false"
soapVersion="1.2" />
</http:outbound-endpoint>
</flow>
http://www.webservicex.net/stockquote.asmx?wsdl gives the same result. So you could test it there. Maybe the problem lies with .net services.
Anyway, for now I made a successful proxy with the webservice pattern. Now I am still working on transforming a response. Not with much success because Mule keeps giving me a ReleasingInputStream as response.

How do I rename a file using the SharePoint web services?

I have a custom definition for a document library and I am trying to rename documents within the library using only the out of the box web services. Having defined a view with the "Name" field supplied and trying the "LinkFilename", my calls to rename a file are respectively returning a failure or ignoring the new value.
How do I rename a file using the SharePoint web services?
Use the Lists.UpdateListItems web method. The XML request should look like:
<Batch OnError="Continue" PreCalc="TRUE" ListVersion="0">
<Method ID="1" Cmd="Update">
<!-- List item ID of document -->
<Field Name="ID">2</Field>
<!-- Full URL to document -->
<Field Name="FileRef">http://Server/FullUrl/File.doc</Field>
<!-- New filename -->
<Field Name="BaseName">NewName</Field>
</Method>
</Batch>
You should be able to use UpdateListItems. Here's an example.
Per comment: So the actual question is "how do I call a web service?" Take a look a this example. Some more good walkthroughs here.