What is the query string of a BlazeDS request? - http

I have a Tomcat service running on localhost:8080 and I have installed BlazeDS. I created and configured a simple hello world application like this...
package com.adobe.remoteobjects;
import java.util.Date;
public class RemoteServiceHandler {
public RemoteServiceHandler()
{
//This is required for the Blaze DS to instantiate the class
}
public String getResults(String name)
{
String result = “Hi ” + name + “, the time is : ” + new Date();
return result;
}
}
With what query string can I invoke RemoteServiceHandler to my Tomcat instance via just a browser? Something like... http://localhost:8080/blazeds/?xyz

Unfortunately you can't. First the requests (and responses) are encoded in AMF and second I believe they have to be POSTs. If you dig through the BlazeDS source code and the Flex SDK's RPC library you can probably figure out what it's sending. But AFAIK this hasn't been documented anywhere else.

I think that AMFX (which is AMF in XML) will work for you, using HTTPChannel instead of AMFChannel.
From http://livedocs.adobe.com/blazeds/1/blazeds_devguide/help.html?content=lcarch_2.html#1073189, Channels and channel sets:
Flex clients can use different channel
types such as the AMFChannel and
HTTPChannel. Channel selection depends
on a number of factors, including the
type of application you are building.
If non-binary data transfer is
required, you would use the
HTTPChannel, which uses a non-binary
format called AMFX (AMF in XML). For
more information about channels, see
Channels and endpoints.
This way you can use simple netcat to send the request.
Not sure how authentication will be handled though, you will probably need do a login using Flash, extract the authentication cookie and then submit it as part of your request.
Please update this thread once you make progress so that we all can learn.

Related

Spring-Security-OAuth2 - how to add fields to access token request?

I have a Spring Boot application, that is using Spring Security with OAuth 2.0. Currently, it is operating against an Authentication Server based on Spring Example code. However, running our own Auth Server has always been a short-term target to facilitate development, not a long-term goal. We have been using the authorization_code grant type and would like to continue using that, irrespective of the Auth Server implementation.
I am attempting to make changes to use OAuth 2.0 Endpoints in Azure Active Directory, to behave as our Authentication Server. So far, I have a successful call to the /authorize endpoint. But the call to get the /token fails with an invalid request error. I can see the requests going out.
It appears that parameters that Azure states as mandatory are not being populated in the POST request. Looking at the Azure doco, it expects the client_id to be defined in the body of the message posted to the endpoint, and that is not added, by default, by Spring.
Can anyone point me in the right direction for how I can add fields to the Form Map that is used when constructing the Access Token request? I can see where the AccessTokenRequest object is being setup in OAuth2ClientConfiguration....
#Bean
#Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
protected AccessTokenRequest accessTokenRequest(#Value("#{request.parameterMap}")
Map<String, String[]> parameters, #Value("#{request.getAttribute('currentUri')}")
String currentUri) {
DefaultAccessTokenRequest request = new DefaultAccessTokenRequest(parameters);
request.setCurrentUri(currentUri);
return request;
}
Should I be trying to define the map in a request.parameterMap spring property? If so, I'm not too sure how that works.
Or should I be using one of the interfaces defined in the AuthorizationServerConfigurerAdapter class?
I have the information to include when sending the AccessTokenRequest, I just don't know the best way to configure Spring to include it? Thanks for any help.
Actually, I found this out. I needed to change the client authentication scheme. Simply adding the following to my application properties added the client_id to the form....
security.oauth2.client.clientAuthenticationScheme=form
If you're using yaml, then yaml-ize it. Thank you Spring!

Spring Integration calling Apache Solr RESTful service

I would like to call Apache Solr using Spring Integration. Solr provides RESTful like features for searching e.g. I want to call: http://localhost:8983/solr/#/ccy/query?q=id:*&wt=json this will return a json string.
So the plan is to provide a ReferenceData Controller which calls a service which in turn will call Solr via spring integration. But I need the response to be Synchronous.
I have looked at the sample Spring Integration code provided and came across rest-http example . But it want over my head. So how can I do this and any code sample would be useful.
Thanks
GM
The rest sample is concentrated on the server side; on the client side, you'd need something like...
<int:gateway id="toRest" default-request-channel="foo" service-interface="ToRest" />
<int:channel id="foo" />
<int-http:outbound-gateway id="out" request-channel="foo"
http-method="GET"
url="http://localhost:8983/solr/ccy/query?q=id:{currency}&wt=json">
<int-http:uri-variable name="currency" expression="headers['currency']"/>
</int-http:outbound-gateway>
With ToRest being a Java interface with a method something like String toRest(String in); inject the ToRest instance into your controller and just send an empty String "".
However, I think that # in the middle of the URL is going to give you trouble.
EDIT:
Added uri-variable - the expression can be any SpEL expression, e.g. payload.currency (calls getCurrency() on the message payload); headers['currency']; or #someBean.determineCurrency(payload); etc, etc.
Your gateway can populate the header...
String result(#Payload String payload, #Header("currency") String currency);
Of course, since you are only doing a GET, you could simply set the currency in the payload and just use expression="payload".
Regarding the hash tag, please have a look at: http://en.wikipedia.org/wiki/Fragment_identifier
The fragment identifier functions differently than the rest of the URI: namely, its processing is exclusively client-side with no participation from the web server

WebTest for SignalR possible?

if I send a request, and I expect the response to come trough SignalR, is it possible to test this using a LoadTest or PerformanceTest in Visual Studio?
Short answer: Yes
I've done this several times in CodedWebTests but it would also be possible to do in a declarative WebTest. You can use a custom PreWebTest Event Handler to create your signalR client and connect to your SignalR hub. What you choose to do with the signalR notification is up to you but I like to save it to the WebTestContext as well as display it on the test results screen using the AddCommentToResult method.
The method below creates a hubConnection invokes the "addToGroup" function on the hub and then tells the client what to do when it receives a message.
using Microsoft.AspNet.SignalR.Client;
public class SignalRPlugin : WebtTestPlugin
{
public override void PreWebTest(object sender, PreWebTestEventArgs e)
{
var hubConnection = new HubConnection("yourSignalRUrl");
var hubProxy = hubConnection.CreateHubProxy("notifications");
hubConnection.Start().Wait();
hubProxy.Invoke("addToGroup", "me");
hubProxy.On<string>("message", s =>
{
e.Webtest.AddCommentToResult(s);
e.Webtest.Context.Add("signalRMessages", s);
});
}
}
Use it by attaching the event handler in your test constructor.
public MyWebTest()
{
PreWebTest += new SignalRPlugin().PreWebTest;
}
Then once you have the signalR messages you can use a custom validation rule to validate that the response was received. Just have a while loop checking the WebTestContext for the "signalRMessages" key. I strongly suggest making sure you add a timeout feature so you are not waiting forever if the messages never come in.
The other option if you are writing CodedWebTests is to create a WaitForNotifications method that basically does the same thing as the validation rule. The advantage with this is that you can use an extraction rule to get data out of the last response and then use that data in validating your signalR messages. If you still need to fail a test in your WaitForNotification method use WebTest.InternalSetOutcome(Outcome.Fail);
The best way to load test a SignalR application is by building on the crank project included in the source.
This is a simple ramp up solution built with the .Net client but it is relatively easy to modify to call whatever hub methods you require and to analyse the responses.
You can always attach the Visual Studio profiler to your iis express instance to get detailed profiling data if required.

How can I intercept all calls to methods in a WCF .svc service?

Ive got a WCF service which has multiple web methods in it. I want to be able to intercept the request on all methods and look at the Ip address. Id rather not put the logic into a method call at the top of each called web method is there a way to intercept all calls to these methods from one place?
If it was a page I would write a base page object but im nout sure if there are events raised on a wcf call?
WCF allows you to implement interceptors that are added to the stack. See this link for an example. I´m not sure whether this allows you the extract the senders IP but I think it´s worth a try.
You can implement IDispatchMessageInspector and do something like this.
public object AfterReceiveRequest(ref Message request,
IClientChannel channel, InstanceContext instanceContext)
{
RemoteEndpointMessageProperty remoteEndpoint = request.Properties
[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;
//remoteEndpoint.Address will give you the address.
return null;
}
You can use Custom Behaviors, they are part of WCF Extensibility features. Here's more information: Extending WCF with Custom Behaviors
There's a clever way to do this with the ServiceAuthorizationManager, and it's far easier than all the seriously hard work of the IDispatchMessageInspector.
Create a class in your WCF Service project like so:
public class MyServiceAuthorizationManager : ServiceAuthorizationManager
{
protected override bool CheckAccessCore(OperationContext operationContext)
{
string classMethod = operationContext.RequestContext.RequestMessage.Headers.Action;
if (classMethod.Contains("/transfer/Get"))
{
return true; // because someone is simply updating a client service reference
}
Console.WriteLine("Class Method Call: {0}",classMethod);
// do something with operationContext here as you need to inspect stuff
// return true if you want this class method call to succeed and go through
// return false if you want this class method to fail on the client
return true;
}
}
Then, in your service, right before your host.Open() call, add the link to MyServiceAuthorizationManager.
ServiceHost host = new ServiceHost(typeof(MyProject.Service1));
host.Authorization.ServiceAuthorizationManager = new MyServiceAuthorizationManager();
host.Open();
Now when you test your client connections, you'll notice that the console outputs what class method was called. You can also work against all the stuff in the operationContext object.
One way I use this is for a security header check. In my client, I add a header. Then, in the service, in this CheckAccessCore() call, I verify that this custom header exists. If it doesn't, then I return false. This is one more layer of protection that keeps the hackers out, and is great for the limited security in Named Pipes configurations too. If you're wanting to also do that, then click here for more information on how to add custom headers that automatically get sent on every client's method call on the service.
And note, among all this, I didn't have to mess with behaviors, claims, listeners, or message dispatches. I also didn't need to edit my WCF Configuration.
Note the string check for /transfer/Get above. This is important if you're doing header checks as a security mechanism like I was. If you don't have that condition and return true, then your WCF client IDE can't update its ServiceReference because the IDE doesn't know about that extra header (if you're adding a custom header and not specifying that header in the WCF client's app.config). Otherwise, you'll get an error The URI prefix is not recognized.

How to set an HTTP header while using a Flex RemoteObject method?

I am running blazeds on the server side. I would like to filter http requests using an http header. My goal is to send extra parameters to the server without changing the signatures of my blazeds services.
On the client side, I am using Flex RemoteObject methods.
With Flex WebService components, it is possible to set an http header using the property httpHeaders. I have not found anything similar on the RemoteObject class...
I couldnt modify http request from flex, instead I can add custom headers to the mx.messaging.messages.IMessage that RemoteObject sends to the server and there, extending flex.messaging.services.remoting.adapters.JavaAdapter (used for accessing Spring beans), it's posible to read the header parameters and put them into the HTTPRequest.
In the flex part, I had to extend mx.rpc.AsyncRequest:
declares a new property "header" and overwrites invoke method that checks if there is a not null value for set the msg.headers.
and mx.rpc.remoting.mxml.RemoteObject:
the constructor creates a new instance of our custom AsyncRequest and overwrite old AsyncRequest and it defines a setHeaders method that set the argument to the custom AsyncRequest.
com.asfusion.mate.actions.builders.RemoteObjectInvoker (extra :P):
this one reads the param declared in the Mate's map RemoteObjectInvoker and puts in the RemoteObject header.
I hope it will be understandable (with my apache english xDDD)
Bye. Agur!
This worked for me using BlazeDS and Spring-Flex 1.5.2
Flex:
use namespace mx_internal;
var service:RemoteObject = new RemoteObject(destination);
var operation:Operation = service[functionName];
operation.asyncRequest.defaultHeaders = {company:'company'};
var token:AsyncToken = operation.send();
Java Spring-Flex:
public class FlexJavaCustomAdapter extends JavaAdapter{
#Override
public Object invoke(Message message) {
String locale = (String) message.getHeader("com.foo.locale");
return super.invoke(message);
}
}
dispatcher-servlet.xml
<bean id="customAdapter" class="org.springframework.flex.core.ManageableComponentFactoryBean">
<constructor-arg value="com.codefish.model.flex.FlexJavaCustomAdapter"/>
</bean>
<flex:message-broker id="_messageBroker" services-config-path="classpath*:/com/codefish/resources/spring/services-config.xml" >
<flex:remoting-service default-adapter-id="customAdapter"
default-channels="my-amf, my-secure-amf" />
</flex:message-broker>
</bean>
RemoteObject uses AMF as the data channel, and is managed in a completely different way than HttpService or WebService (which use Http).
What you can do, is call setCredentials(username,password) and then capture this on the server side using the FlexLoginCommand (either the standard one for your container, or derive your own).
Lookup setCredentials and how you should handle this on both sides (client and server).
I have similar problem, and I afraid there is no simple way to set HTTP header when using AMF. But I've designed following solution.
Flex uses HTTP to transfer AMF, but invokes it through browser interfaces, this allows you to set cookie. Just in document containing application invoke following JavaScript
document.cookie="clientVersion=1.0;expires=2100-01-01;path=/";
Browser should transfer it to server, and you can filter (problem will be if the user will have cookies turned off).
Much more you can invoke JavaScript functions from Flex (more is here: http://livedocs.adobe.com/flex/3/html/help.html?content=passingarguments_4.html).
You might be trying to re-invent the wheel. Is there a reason you can't use the standard HTTP(s) authentication?
A reason I was thinking too to use http headers was for the server to be able to 'recognize' the flex client in the a context of service versionning.
On the server I can always build an indirection/proxy that would allow the different clients to only use 1 end point and route to the right adapter depending on the client version.
The question is on the client side. How would the server identify the flex client token or 'version'. One way is certainly via authentication. But, assuming there is not authentication involved?
We recently run into the same issue and this is how we added our custom headers without creating a subclass:
var operation:AbstractOperation = _remoteSession.getOperation('myRemoteOperation');
var async:AsyncRequest = operation.mx_internal::asyncRequest;
async.defaultHeaders = {my_header:'my_value'};
The AsyncRequest object is actually accessible via the operation object via the mx_internal namespace.
You can debug the $GLOBALS in PHP to see that.
I think this is in the
$GLOBALS['HTTP_RAW_POST_DATA'];
or you can simple do
file_get_contents('php://input');

Resources