I have a SOAP web service written in Spring Web Services that I would like to integration test.
I would like to use spring-ws-test as the reference documentation points to. So, the test code is similar to the example in the reference, something like that:
#Autowired
private ApplicationContext applicationContext;
private MockWebServiceClient mockClient;
#Before
public void createClient() {
mockClient = MockWebServiceClient.createClient(applicationContext);
}
#Test
public void customerEndpoint() throws Exception {
Source requestEnvelope = new ResourceSource(new ClassPathResource("request.xml"));
Source responsePayload = new ResourceSource(new ClassPathResource("response.xml"));
mockClient.sendRequest(withSoapEnvelope(requestPayload)).
andExpect(payload(responsePayload));
}
However, the endpoint I am testing is using basic authentication and it expects to read values in the Authorization header. It is not using spring-security for that task but it has custom logic that gets the HTTP headers by getting the HttpServletResponse from the TransportContextHolder. So, the request triggers the endpoint but it fails to retrieve the basic authentication base64 token.
The question is, how may I pass HTTP headers in that situation? Is it possible at all? If not what is the preferred alternative?
I have read the javadoc and I cannot find a way to pass the headers. Also, I have found this question which is similar but it doesn't help me much.
Related
We have a couple of Spring tests that call a secured controller endpoints. Our goal is to assure that absence of particular user roles will result into HTTP 403 status.
Our issue is that execution of those tests also bootstraps DB connection which we don't actually need.
I've already tried countless number of all kind of annotations and manual configurations to avoid initialization of DB connection but so far without luck. Can you please share example how to do that?
We use Spring Boot 2.7.
Yes, you can use #WebMvcTest, take a look at the docs. In summary, using #WebMvcTest will only bootstrap the Spring MVC components and avoid loading other application's layers. This annotation also automatically configures Spring Security for you, therefore you can test authentication/authorization rules.
Example:
#WebMvcTest(UserVehicleController.class)
class MyControllerTests {
#Autowired
private MockMvc mvc;
#MockBean
private UserVehicleService userVehicleService;
#Test
#WithMockUser(roles = "ADMIN")
void testAdminSuccess() throws Exception {
given(this.userVehicleService.getVehicleDetails("sboot"))
.willReturn(new VehicleDetails("Honda", "Civic"));
this.mvc.perform(get("/sboot/vehicle").accept(MediaType.TEXT_PLAIN))
.andExpect(status().isOk())
.andExpect(content().string("Honda Civic"));
}
#Test
#WithMockUser(roles = "USER")
void testUserForbidden() throws Exception {
this.mvc.perform(get("/sboot/vehicle").accept(MediaType.TEXT_PLAIN))
.andExpect(status().isForbidden());
}
}
What is the equivalent of MockHttpServletRequestBuilder for websockets. i.e. In a situation where I want to test Websockets., I would like to test a long running websocket application and avoid the situation where SecurityContextPersistenceFilter is overriding the SecurityContex after the first http get call that is supposed to do the upgrade. For plain rest http apps this was done so far by leveraging the SecurityMockMvcRequestPostProcessors.
example here using the SecurityMockMvcRequestPostProcessors
But what to do when I want to test a long running websocket application. i.e. I want ot create something like MockHttpServletRequestBuilder for websockets. Does spring have something like that already? Or is there a way to use MockHttpServletRequestBuilder for that purpose? I.e. the target is to create the websocket endpoint and avoid the situation where the SecurityContex is beeing cleared after the upgrade.
I have found some alternatives such as passing the session as described here but this is not really an alternative for me as then the code that is using method level security does not work since the SecurityContex is being altered.
It appears that this can be done by providing a test sock config. Ex
#EnableWebSocketMessageBroker
static class TestWebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
#Autowired
Environment env;
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/portfolio").withSockJS();
}
#Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
// registry.enableSimpleBroker("/queue/", "/topic/");
registry.enableStompBrokerRelay("/queue/", "/topic/");
registry.setApplicationDestinationPrefixes("/app");
}
}
The full class can be found here:
https://github.com/rstoyanchev/spring-websocket-portfolio/blob/master/src/test/java/org/springframework/samples/portfolio/web/context/ContextPortfolioControllerTests.java
Here are also some additional examples provided by spring the demonstrate 3 different approaches to testing web sockets:
https://github.com/rstoyanchev/spring-websocket-portfolio/tree/master/src/test/java/org/springframework/samples/portfolio/web
I need to implement a requirement in which other non-backbase applications will send a HTTP POST request to my bb application. There is some pre processing & validation which is to be done and then based on the result the client has to be redirected to the login page or an error page.
What is the best way to implement this in backbase?
You need to check the documentation about Integration Services.
The full documentation about you can find here: https://my.backbase.com/docs/product-documentation/documentation//portal/5.6.2/develop_integrationservices.html
The documentation will help you to develop own service (I prefer use Camel Java DSL way), and you will get the url like:
http://localhost:7777/portalserver/services/rest/v1/myService.
here the example of Java implementation of service:
public class MyCamelService extends RouteBuilder {
#Override
public void configure() throws Exception {
from("restlet:/v1/myService")
.setBody().constant("<html><body><b>Hello World!</b></body></html>")
.setHeader("Content-Type", constant("text/html"));
}
}
A client software is trying to access my Spring-MVC rest server, but it's getting a 400 (Bad Request) response every time. I know my server is fine (it's in use by many other clients), but I cannot debug the client application, so I cannot see what it is sending.
Is there a way for me to see what JSON I am receiving before Spring tries to convert it to an entity and fails? It's okay if I can only do this at debug time, I just need to be able to give support to this application's creators.
Just in case, here is the spring-mvc controller method:
#Named
#RequestMapping(value = "/taskmanager/task")
public class TaskManagerTaskRest {
#RequestMapping(value = "", method = RequestMethod.POST)
#ResponseBody
public void createTask(#RequestBody Task task, HttpServletRequest request,
HttpServletResponse response) throws CalabacinException {
// This code never gets executed because the Task json is invalid, but I don't know how I could see it.
...
...
}
}
Try to use Fiddler. It will help you to catch HTTP requests/responses. You will be able to see your JSON.
You can create and use a AbstractRequestLoggingFilter filter implementation and conditionally log the relevant parts of the request. You should use ContentCachingRequestWrapper to wrap the request.
I am performing acceptance tests against REST services written using Jersey. In my services, I need to get the name of the user who successfully authenticated (BASIC) using:
#Context private SecurityContext securityContext; //at class level
String username = securityContext.getUserPrincipal().getName() //inside a resource
I am using the Jersey client API and running against the Grizzly server. I set up the server as follows:
public class BaseResourceTest extends JerseyTest {
public BaseResourceTest() throws Exception {
super(new WebAppDescriptor.Builder("net.tds.adm.na.batchcut")
.contextPath(baseUri.getPath())
.contextParam("contextConfigLocation","classpath:testContext.xml")
.initParam("com.sun.jersey.api.json.POJOMappingFeature",
"true").servletClass(SpringServlet.class)
.contextListenerClass(ContextLoaderListener.class)
.build());
}
.......
}
In my tests, I pass an authorization header as follows:
WebResource resource = resource().path(_url);
return resource.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE).header(HttpHeaders.AUTHORIZATION, new String(Base64.encode("judge:smails"))).post(ClientResponse.class, _formData);
However, in my resources I get an NPE when trying to get the user name. I think I need to get the server to actively authenticate against a realm but I haven't found how to configure the server to do this. Has anybody had any experience with this?
Unfortunately Grizzly HttpServer doesn't support authentication at the moment.
But here you can find a simple example how to implement authentication using Jersey Filter.
http://simplapi.wordpress.com/2013/01/24/jersey-jax-rs-implements-a-http-basic-auth-decoder/