how does spring cloud zuul get request parameter when content type is multipart/form-data? - netflix-zuul

I need to upload file through zuul to my application, the content type is multipart/form-data, but I have some other parameters in the request.
So how can I get the parameters in the zuul?
I want to get the token to check the request is valid or not.
I've tried "request.getParameter("token");",but it does not work.

if you Get request through
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = context.getRequest();
the call request.getParameter("token"); It does not return any valid values
This away may solve this issue
HttpServletRequestWrapper httpServletRequestWrapper = (HttpServletRequestWrapper) request;
String token = httpServletRequestWrapper.getRequest().getParameter("token");
ps:
I suggest you check the request type first before getting the value.by this way
String requestType = request.getContentType().split(";")[0];
if(MediaType.MULTIPART_FORM_DATA_VALUE.equls(requestType)){
HttpServletRequestWrapper httpServletRequestWrapper = (HttpServletRequestWrapper) request;
token = httpServletRequestWrapper.getRequest().getParameter("token");
}

Related

Where is the OAuth2.0 Authorization Code stored?

I'm developing a C# application that needs to contact a web-based API. When contacting the API, the first thing it does is try to get an authorization code from an authorization server. Using RestSharp, my code is this:
static string GetAuthCode(string authUri, string clientId, string scope, Guid state, string callbackUri)
{
var client = new RestClient(authUri);
var request = new RestRequest("", Method.Post);
client.Options.MaxTimeout = -1;
request.AddParameter("client_id", clientId);
request.AddParameter("response_type", "code");
request.AddParameter("scope", scope);
request.AddParameter("state", state);
request.AddParameter("redirect_uri", callbackUri);
RestResponse response = client.Execute(request);
if (response.IsSuccessful)
{
string code = HttpUtility.ParseQueryString(response.ResponseUri.Query).Get("code");
return code;
}
else
throw new Exception(response.Content);
}
When I call this method, the response is successful, however I was expecting that the resulting authorization code would be appended to the ResponseUri property of the response (in its Query property). But it's not. The ResponseUri property is set to the authorization Uri (authUri). Am I looking in the wrong spot for the authorization code? Where can I find the actual authorization code?
It should be in the query parameters:
If the resource owner grants the access request, the authorization
server issues an authorization code and delivers it to the client by
adding the following parameters to the query component of the
redirection URI using the "application/x-www-form-urlencoded" format,
per Appendix B:
4.1 Authorization Code Grant - 4.1.2 Authorization Response

How to get request payload from POST request in struts custom interceptor?

Each request in my app goes through the custom interceptor where it validates the sessionid filed value which is passed as the one of the parameters in the request payload(post method).
If it is url paramter then we can use following snippet to catch the parameter.
Map<String, Object> parameters =
actionInvocation.getInvocationContext().getParameters();
String sessionid = parameters.get("sessionId");
What could be the way to catch this parameter in interceptor if "sessionId" being sent as part request payload.
I tired below code snippet to catch in the interceptor and it is working fine but in later stages in action classes body is not available to read.if we read twice then request body is not available for the second time to read.
public String intercept(ActionInvocation actionInvocation) throws Exception {
Log.debug(getClass().getName(), "intercept", "Debug enter");
ActionContext context = actionInvocation.getInvocationContext();
HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST);
RestPostBody restBody= new Gson().fromJson(request.getReader(), RestPostBody.class);
}

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

maintaining sessions with RestAssured

How to set session attributes in restassured? In my application code we have something like this
String userId= request.getSession().getAttribute("userid")
How to set userId as session attribute here(in restassured test case)?
How to maintain the same session for all the requests(multiple subsequent requests)?
When i send multiple requests, it's considering every request as new and session is getting invalidated from server side, i want to maintain session between subsequent calls.
I tried setting jsessionid in the cookie and sent it in the second request, but when i debugged in the server side, it's not loading the session which was created, instead it's creating different session and because of this its doesn't show the attribute which i have set in the session when i first sent the request.
When i tried the same with direct HttpClient, it working, where as the same with RestAssured it's not working.
Code which was working with HttpClient is this
HttpClient httpClient = util.getHttpClient();
//1st request
HttpResponse response=httpClient.execute(postRequest);
from response i have extracted the jessionid and set this in the second request
HttpGet getRequest = new HttpGet(Client.endPointUrl);
getRequest.addHeader("content-type", "application/json");
getRequest.addHeader("accept", "application/json");
getRequest.addHeader("Origin", Client.endPointUrl);
getRequest.addHeader("Referer", Client.endPointUrl);
getRequest.addHeader("Auth-Token", authToken);
getRequest.addHeader("Set-Cookie", jsessionId);
//2nd request after setting the jessionid which i have extracted from the response
HttpResponse eventsResponse = httpClient.execute(getRequest);
Above code is working perfectly fine and i am getting expected response. One observation is i am using the same httpClient Object for invoking both the requests.
Where as i if i try the same using RestAssured, it's not working.
RestAssured.baseURI = "http://localhost:8080";
Response response=RestAssured.given().header("Content-Type","application/json").
header("Origin","http://localhost:8080").
header("Referer","http://localhost:8080").
body("{"+
"\"LoginFormUserInput\":{"+
"\"username\":\"test\","+
"\"password\":\"password\""+
"}"+
"}")
.when().post("/sample/services/rest/validateLogin").then().extract().response();
JsonPath js=Util.rawToJson(response);
String sessionId=js.get("sessionID");
System.out.println(sessionId);
for (Header header:response.getHeaders()) {
if ("Set-Cookie".equals(header.getName())) {
id= header.getValue().split(";")[0].trim();
String[] arr=jsessionId.split("=");
jsessionId=arr[0];
break;
}
}
response=RestAssured.given().header("Auth-Token",sessionId).header("Content-Type","application/json").
cookie("JSESSIONID",jsessionId).
header("Origin","http://localhost:8080").
header("Referer","http://localhost:8080").
body("{}").
when().
post("/sample/services/rest/getAllBooks").then().contentType("").extract().response();
I tried reusing the same httpclient for all the requests using the following, but it didn't work
RestAssured.config = RestAssured.config().httpClient( new HttpClientConfig().reuseHttpClientInstance());
You need to use Session filter in Rest Assured
https://github.com/rest-assured/rest-assured/wiki/Usage#session-support

Setting param from portlet URl into HttpServletRequest

I am referring to a url which has paramID from my portlet. The content of that paramID is handled in different portlet and it has its own controller.
That controller is taking HttpServletRequest to read that param.
HttpServletRequest request = PortalUtil.getOriginalServletRequest(PortalUtil.getHttpServletRequest(renderRequest));
String paramID= request.getParameter("paramID");`
My param is in the url http://mysite.com?paramID=123
Will the HttpServletRequest read this param when I am calling using renderURL
<liferay-portlet:renderURL var="xyz" portletName="ABC" windowState="Normal"/>
...
Click here
Some information about render URL and such is under this question on its community wiki answer.
Also in some tutorial that is not on web I have read this kind of parameter passing is easiest done via session. Session is common for porlet and servlet so you don't have to think where the which parameter is visible and where not.
I did it with providing the param value while I invoked the renderURL
<liferay-portlet:renderURL var="xyz" portletName="ABC" windowState="Normal"/>
</liferay-portlet:renderURL>
.....
<JAVASCRIPT>
var URL = NULL;
function(called){
URL = "${xyz}&paramID=123" //and this was read as servlet param
}
</JAVASCRIPT>

Resources