Dart request succeeding ... somehow? - dart

I'm developing a dart application which will consume a REST service I'm building. I started writing out the dart code to perform an ajax request to my login endpoint. However, even when my dart ajax request should fail, it claims to succeed.
I don't have any services up and running (and even if I did it would be using the wrong domain / port right now), but this code gives a 200 OK HttpResponse every time:
class PlayerController {
const PlayerController();
static const String LOGIN_URL = "login";
void login(String username, String password) {
Map<String, String> headers = {"Content-Type": "application/x-www-form-urlencoded"};
String body = "j_username=$username&j_password=$password&submit=Login";
HttpRequest.request(LOGIN_URL, method: "POST", requestHeaders: headers, sendData: body)
.then((request) => processLogin(request, username))
.catchError((e) => processLoginError(e));
}
void processLogin(var whatIsThis, String username) {
query("#loginButton").text = "Logout";
//TODO get the player then set them
}
void processLoginError(var e) {
print("total failure to login because of $e");
}
}
It always hits the processLogin method, and never hits the processLoginError method. Does anyone have any idea why this would be? Should I be performing this ajax request in a different way? (If you couldn't guess, it will be signing into spring security).
I read somewhere that file system requests always succeed. Is Dart somehow making this a file system request rather than a web request?

This is because the request actually completes successfully.
Your request to "login" will actually call http://127.0.0.1:6521/[Path_to_your_Dart_file]/login
The server started by Dart when running in Dartium (127.0.0.1:6521) seems to answer to every POST request with HTTP 200 and an empty response body.
If you change the method from POST to GET, it will fail as expected.
As for why the server does this - I don't really know. This would have to be answered by the Dart team.

Related

How to add CORS middleware in shelf with router?

I am new to server side programming with dart. I made a simple API server with a number of get routes. I am handling this as follow,
Router router = Router();
router.get('/', checkSTATUS);
router.get('/login/<user>/<pass>', (Request request, String user, String pass) async {
id = 0;
// stuff
return Response.ok(json.encode({"status":"found","id":id}));
});
router.get('/update', (Request request) async {
//stuff
return Response.ok(json.encode({"status": "updated", "data": updated}));
});
//for any other requests
router.all('/<ignored|.*>', (Request request) {
return Response.notFound(json.encode('Page not found'));
});
final server = await serve(
router,
InternetAddress.anyIPv4,
8080,
);
I can access these routes using postman but making requests using flutter web results in error. I searched and found out that this may be CORS related. But how do I add the CORS headers without disrupting the entire code.
Please refer this document. https://pub.dev/packages/shelf_cors_headers.
Install this package

"Post" of the dependency injection in Azure Function has some strange problems

I am trying out the dependency injection for Azure Function.
I have the following super simple code block
[FunctionName("CosmosWriteTest")]
public async Task<IActionResult> CosmosWriteTest([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
return new OkObjectResult("");
}
As you can see, the type of this function is Post. I then copy the URL of this function from the console and paste it into the web browser. I received the "This localhost page can’t be found" error.
I tried to modify the type from post to get, or to "post, get", it works.
Any idea what's going on here?
Here is the http-triggered Function's description from official document:
The HTTP trigger lets you invoke a function with an HTTP request. You
can use an HTTP trigger to build serverless APIs and respond to
webhooks.
You could run a function from an HTTP request (http trigger) and return an HTTP response from a function (http output) using Postman and curl, or access the url with the query string like this:
If you are using portal, you can also test it directly:

Is there a way to change http request method in netflix zuul routing filter?

I'm trying to trasform http GET method call from legacy api server built with MVC1 pattern to new restful api server without any change of front-end source code using netflix zuul and eureka.
I added zuul pre filter transforming legacy url to restful convention url working after PreDecorationFilter and it works fine.
But now I'm facing problem converting the GET method to proper method like POST, PUT, DELETE by distinguising url so that the requests are properly mapped in spring controller via #GetMapping/#PostMapping/#PutMapping/#DeleteMapping.
I looked into SimpleRoutingFilter that handles HttpClient but
Because of environmental constraint, I have to use eureka service id to route to the new api server and that means I should use RibbonRoutingFilter which is quite complicated to find out a right place to this operation in.
So, is this possible to change http method or make new http request before RibbonRoutingFilter?
If possible can you please suggest where is the right place to do that or some reference?
Many thanks!
======================================================================
Milenko Jevremovic,
Would you please tell me more detail about using Feign?
I defiend #FeignClient like below
#PostMapping(value = "{url"}, consumes = "application/json")
ResponseEntity<?> postMethod(#PathVariable("url") String url);
and to get query parameters to request body for POST In zuul pre filter,
after transform logic from GET request url to POST new restful url ...
byte[] bytes = objectMapper.writeValueAsBytes(ctx.get("requestQueryParams"));
ctx.setRequests(new HttpServletRequestWrapper(request) {
#Override ..getMethod
#Override ..getContentLength
#Override ..getConentLengthLong
#Override
public ServletInputStream getInputStream() {
return new ServletInputStreamWrapper(bytes);
}
}
ResponseEntity<?> response feignClient.post(transformedNewApiUri);
and set RequestContext code that you suggested ....
and controller of new api server is like,
#PostMapping
ResponseEntity<model> post(#RequestBody req..)
It comes to controller fine but when I see the http request in post method of controller,
There is no request body for parameters.
(HttpServleterRequest getInputStream shows empty)
The request data set in zuul pre filter by HttpServletRequestWrapper is
not used in Feign maybe...?
Would you please get me more idea setting request body when changing GET query
to POST constructor for using Feign?
It is not possible to change method of HttpServletRequest, but it's possible to replace request in RequestContext. HttpServletRequestWrapper appears to be very helpful:
static class PostHttpServletRequest extends HttpServletRequestWrapper {
public PostHttpServletRequest(HttpServletRequest request) {
super(request);
}
#Override
public String getMethod() {
return "POST";
}
}
So method run can be rewritten as following:
#Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
HttpServletRequest requestWrapper = new PostHttpServletRequest(request);
ctx.setRequest(requestWrapper);
return null;
}
After doing some research did not find any built in solution.
But what comes in my mind you can use Feign client in your Pre filter, get the response, set the response and return it immediately to client from your Pre filter.
You can set Feign client url or your service id, like it is explained in the docs, it uses ribbon as well .
Change response in your run method like:
...
RequestContext ctx = RequestContext.getCurrentContext();
ctx.setResponseStatusCode(your_code);
ctx.setResponseBody(new_body);
ctx.setSendZuulResponse(false);
return null

What could cause the original 'OAuth2' state parameter to be null in org.springframework.social.connect.web.ConnectSupport?

I am trying to use Spring Social on my application and I noticed while debugging that the original 'OAuth2' state parameter is always null on my app.
See Spring Social source code for org.springframework.social.connect.web.ConnectSupport below:
private void verifyStateParameter(NativeWebRequest request) {
String state = request.getParameter("state");
String originalState = extractCachedOAuth2State(request);//Always null...
if (state == null || !state.equals(originalState)) {
throw new IllegalStateException("The OAuth2 'state' parameter is missing or doesn't match.");
}
}
private String extractCachedOAuth2State(WebRequest request) {
String state = (String) sessionStrategy.getAttribute(request, OAUTH2_STATE_ATTRIBUTE);
sessionStrategy.removeAttribute(request, OAUTH2_STATE_ATTRIBUTE);
return state;
}
Can anyone please help?
edit: I do see the state parameter being passed back by facebook:
Request URL:https://www.facebook.com/v2.5/dialog/oauth?client_id=414113641982912&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fconnect%2Ffacebook&scope=public_profile&state=0b7a97b5-b8d1-4f97-9b60-e3242c9c7eb9
Request Method:GET
Status Code:302
Remote Address:179.60.192.36:443
edit 2: By the way, the exception I get is the following:
Exception while handling OAuth2 callback (The OAuth2 'state' parameter is missing or doesn't match.). Redirecting to facebook connection status page.
It turned out that the issue was caused by the fact that I was relying on headers - as opposed to cookies - to manage the session.
By commenting out the following spring session configuration bean:
#Bean
public HttpSessionStrategy sessionStrategy(){
return new HeaderHttpSessionStrategy();
}
The oauth2 state parameter issue was sorted.
P.S. Now I have got to find a way to get Spring Social to work with my current configuration of Spring Session...
Edit: I managed to keep the HeaderHttpSessionStrategy (on the spring session side) and get it to work by implementing my own SessionStrategy (on the spring social side) as follows:
public class CustomSessionStrategy implements SessionStrategy {
public void setAttribute(RequestAttributes request, String name, Object value) {
request.setAttribute(name, value, RequestAttributes.SCOPE_SESSION);
}
public Object getAttribute(RequestAttributes request, String name) {
ServletWebRequest servletWebRequest = (ServletWebRequest) request;
return servletWebRequest.getParameter(name);
}
public void removeAttribute(RequestAttributes request, String name) {
request.removeAttribute(name, RequestAttributes.SCOPE_SESSION);
}
}
Try this work around and see if that works for you:
To my surprise I opened application in a 'incognito' browser and everything worked. Just like that. I think before something got cached and was causing the issue.
I ran into this issue today, My application was working perfectly fine. I just took a break for few hours and when I ran it again it started complaining about 'The OAuth2 'state' parameter is missing or doesn't match.'
The state param is first put into the session then the request goes out to facebook and the request comes back with the same state param but when spring is looking for session object to get the state param, it is not finding the session. I think it is not finding the session because when the request comes back it thinks that it is a different client (or host), even though the old HttpSession object still exists. The container maintains a HttpSession per client.
What you're getting from Facebook is not a request attribute , it's a request parameter.
You should get it by something like:
request.getParameter("state")

GetClientAccessToken having clientIdentifier overwritten to null by NetworkCredential

I've been trying to get the GetClientAccessToken flow to work with the latest release 4.1.0 (via nuget), where I'm in control of all three parties: client, authorization server and resource server.
The situation I have started to prototype is that of a Windows client app (my client - eventually it will be WinRT but its just a seperate MVC 4 app right now to keep it simple), and a set of resources in a WebAPI project. I'm exposing a partial authorization server as a controller in the same WebAPI project right now.
Every time (and it seems regardless of the client type e.g. UserAgentClient or WebServerClient) I try GetClientAccessToken, by the time the request makes it to the auth server there is no clientIdentifier as part of the request, and so the request fails with:
2012-10-15 13:40:16,333 [41 ] INFO {Channel} Prepared outgoing AccessTokenFailedResponse (2.0) message for <response>:
error: invalid_client
error_description: The client secret was incorrect.
I've debugged through the source into DNOA and essentially the credentials I'm establishing on the client are getting wiped out by NetworkCredential.ApplyClientCredential inside ClientBase.RequestAccessToken. If I modify clientIdentifier to something reasonable, I can track through the rest of my code and see the correct lookups/checks being made, so I'm fairly confident the auth server code is ok.
My test client currently looks like this:
public class AuthTestController : Controller
{
public static AuthorizationServerDescription AuthenticationServerDescription
{
get
{
return new AuthorizationServerDescription()
{
TokenEndpoint = new Uri("http://api.leave-now.com/OAuth/Token"),
AuthorizationEndpoint = new Uri("http://api.leave-now.com/OAuth/Authorise")
};
}
}
public async Task<ActionResult> Index()
{
var wsclient = new WebServerClient(AuthenticationServerDescription, "KieranBenton.LeaveNow.Metro", "testsecret");
var appclient = new DotNetOpenAuth.OAuth2.UserAgentClient(AuthenticationServerDescription, "KieranBenton.LeaveNow.Metro", "testsecret");
var cat = appclient.GetClientAccessToken(new[] { "https://api.leave-now.com/journeys/" });
// Acting as the Leave Now client we have access to the users credentials anyway
// TODO: CANNOT do this without SSL (turn off the bits in web.config on BOTH sides)
/*var state = client.ExchangeUserCredentialForToken("kieranbenton", "password", new[] { "https://api.leave-now.com/journeys/" });
// Attempt to talk to the APIs WITH the access token
var resourceclient = new OAuthHttpClient(state.AccessToken);
var response = await resourceclient.GetAsync("https://api.leave-now.com/journeys/");
string sresponse = await response.Content.ReadAsStringAsync();*/
// A wrong one
/*var wresourceclient = new OAuthHttpClient("blah blah");
var wresponse = await wresourceclient.GetAsync("https://api.leave-now.com/journeys/");
string wsresponse = await wresponse.Content.ReadAsStringAsync();
// And none
var nresourceclient = new HttpClient();
var nresponse = await nresourceclient.GetAsync("https://api.leave-now.com/journeys/");
string nsresponse = await nresponse.Content.ReadAsStringAsync();*/
return Content("");
}
}
I can't figure out how to prevent this or if its by design what I'm doing incorrectly.
Any help appreciated.
The NetworkCredentialApplicator clears the client_id and secret from the outgoing message as you see, but it applies it as an HTTP Authorization header. However, HttpWebRequest clears that header on the way out, and only restores its value if the server responds with an HTTP error and a WWW-Authenticate header. It's quite bizarre behavior on .NET's part, if you ask me, to suppress the credential on the first outbound request.
So if the response from the auth server is correct (at least, what the .NET client is expecting) then the request will go out twice, and work the second time. Otherwise, you might try using the PostParameterApplicator instead.

Resources