I'm new in the play framework. I'm using play 2.8.x framework and I need to get from the controller session object and params from request. But I don't realize how to do that.
My routes file looks like the following:
POST /api/verifyToken/:token controllers.UserController.verifyToken(token: String, request: Request)
and my controller looks like this:
public class UserController extends Controller {
public Result verifyToken(String token, Http.Request request) {
...
}
}
and when I try to send a request to the server I had had an error but if I remove token parameter all is working fine. How can I pass the request and params to the controller?
Your handler is given the Http.Request when it is called:
java.util.Map<java.lang.String,java.lang.String[]> queryParams = request.queryString();
for the session:
Http.Session session = request.session();
Related
I want to be able to fetch a param from the redirect url whenever it is automated. I am having difficulties doing this as I am getting a bad request after I created another endpoint to effect this.
I have an endpoint that works fine. The endpoint is a get method. Loading the endpoint takes a user to a page where they need to provide some necessary details. Once these details have been verified, the user is redirected to my redirecr_uri. The redirect_uri now contains important information like session_id, code, etc. The most important thing I need is the code. I need to pass the code into yet another endpoint which will return an access token.
I have manually done this process and it works but I want it to be done automatically because I can't keep doing that when I push the code to staging or production.
Here is the endpoint that redirects as well as the method.
#GetMapping("/get-token")
public RedirectView getBvn() throws UnirestException {
return nibss.getAccessToken();
}
This is the method that the controller calls
public RedirectView getAccessToken() throws UnirestException {
String url = "https://idsandbox.nibss-plc.com.ng/oxauth/authorize.htm?scope=profile&acr_values=otp&response" +
"_type=code&redirect_uri=https://www.accionmfb.com/&client_id=0915cd00-67f2-4768-99ac-1b2ff9f1da2e";
RedirectView redirectView = new RedirectView();
redirectView.setUrl(url);
return redirectView;
}
When the user provides the right information they are redirected to something like this
https://www.accionmfb.com/?code=9ad91f13-4698-4030-8a8f-a857e6a9907e&acr_values=otp&scope=profile&session_state=fa525cabc5b62854c73315d0322fd830c12a5941b89fd8e6e518da369e386572.b78a3d21-e98e-4e9a-8d60-afca779d9fad&sid=fd60ab92-ef37-4a5b-99b9-f8f52321985d
It is important to state that this 3rd party API I am trying to consume uses oath2.0 client authentication.
I created this endpoint to get the code from the redirected_uri
#GetMapping("/redirect-url")
public void handleRedirect(#RequestParam("code") String code) throws UnirestException {
if(Objects.nonNull(code) || !code.isEmpty()){
nibss.getToken(code);
log.info("Code is not being passed {}", code);
} else {
log.info("Code is not being passed {}", code);
}
}
public String getToken(String code) throws UnirestException {
log.info("This is the code here oooooooooo {}", code);
String url = "https://idsandbox.nibss-plc.com.ng/oxauth/restv1/token";
String parameters = "client_id=0915cd00-67f2-4768-99ac-1b2ff9f1da2e&code="+code+"&redirect_uri=https://www.accionmfb.com/&grant_type=authorization_code";
HttpResponse<String> apiResponse = Unirest.post(url)
.header("Content-Type", "application/x-www-form-urlencoded")
.header("Authorization", "Basic MDkxNWNkMDAtNjdmMi00NzY4LTk5YWMtMWIyZmY5ZjFkYTJlOlRVRnEwcGFBQXRzbzBZOEcxMkl2WFZHUmx6WG5zaERiaGt1dzI1YUM=")
.body(parameters)
.asString();
//JSONObject apiJson = apiResponse.getBody().getObject();
//return apiJson.getString("access_token");
JSONObject json = new JSONObject(apiResponse.getBody());
String accessToken = json.getString("access_token");
log.info(accessToken);
return accessToken;
}
But this is not working, I get 400 whenever I hit the second endpoint. What am I doing wrong?
The redirect_uri that you are passing to the OAuth server is https://www.accionmfb.com which does not include the path /redirect-url so the redirect never hits your method.
Either register and pass a callback uri like redirect_uri=https://www.accionmfb.com/redirect-url
Or change #GetMapping("/redirect-url") to #GetMapping("/")
I am having a piece of code like below for calling one of our service.
MultiValueMap<String, String> parametersMap = new LinkedMultiValueMap<>();
parametersMap.add("query", query);
parametersMap.add("locale", "en_US");
parametersMap.add("resultsLimit", Boolean.FALSE.toString());
parametersMap.add("maxResults", maxResults);
parametersMap.add("type", "TTT");
parametersMap.add("ids", commaSeparatedValues(ids));
parametersMap.add("infoTypes", "HHH,JJJ");
HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(parametersMap, getHttpHeaders());
MyEntity myEntity = restTemplate.postForEntity("http://example.com", httpEntity, MyEntity.class);
And at the server side the controller code is like
#RequestMapping("my/service")
public MyEntity suggest(#RequestParam(required = true) String query, #RequestParam(required = true) String locale,
#RequestParam(required = false) String resultsLimit, #Valid OtherOptions options)
and the OtherOption class is like
class OtherOptions {
String maxResults;
String type;
String ids;
String infoTypes;
}
Here everything is working fine, but I am confused about somethings like .
Is it a get or post request ?
How is some of the parameter maps content become request params(query params) and some others got mapped to the Object of OtherOptions ?
Which is the actual body of the request ?
Is it a get or post request ?
It is a post request. you are calling restTemplate.postForEntity. But your server side method is not restricted as you didn't specify the method attribute for RequestMapping so same method can handle any http method from the point of server.
How is some of the parameter maps content become request params(query params) and some others got mapped to the Object of OtherOptions?
None of them are query params.
See the spring docs for the meaning of #RequestParam. In your case, it all comes from body and not as query params
https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestParam.html
https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html#postForEntity-java.net.URI-java.lang.Object-java.lang.Class-
The body of the entity, or request itself, can be a MultiValueMap to create a multipart request.
Which is the actual body of the request?
parametersMap is the body of the http request.
Note:
Currently your call should fail because you are posting it to http://example.com at client and listening at server side on my/service
I'm a little new in Java Spring. What I want to do is as follows:
Some 3rd party is asking a "return URL" from me and I set it as follows:
https://localhost:9002/my-account/order-history
Then they send me a POST request and I'm supposed to handle it within my controller. The request has both url parameters and a form data. The request is
Request URL:https://localhost:9002/my-account/order-history?responseCode=0000&token=E0ECFC1214B19E5D11B9B587920FC5F164C5CB17E7DC67F083E0EC6676F79467DFBDF4B6CCF3C39BF47F0232D1AA42F1FA112F29B0157DDF98EE3997F781CCB1FEB070A44E530691BA36674BEA4CF56A4A43F2B9746D9C3591CF288D745A6694
Request Method:POST
Status Code:403 Bad or missing CSRF token
Remote Address:127.0.0.1:9002
Referrer Policy:no-referrer-when-downgrade
A part of the form data is:
I added the whole form data and other request info as attachment.
The controller I'm desperately trying to use is as follows:
#Controller
#RequestMapping(value = "/my-account")
public class MaviAccountPageController extends MaviAbstractController
{
#RequestMapping(value = "/order-history", method = RequestMethod.POST)
public ModelAndView process(#RequestBody final String req)
{
//consumes = "text/plain"
System.out.println(req);
System.out.println(req);
return new ModelAndView("deneme");
}
....
}
And I keep getting 403 - Bad or missing CSRF token error.
How should I implement my controller? I have checked below links and they did not work out unfortunately:
How to retrieve FORM/POST Parameters in Spring Controller?
How to explicitly obtain post data in Spring MVC?
I tried, but failed to regenerate issue on postman.
Can anyone, please, advise me about how to move on?
you can annotate your method with #CrossOrigin
#CrossOrigin
#RequestMapping(value = "/order-history", method = RequestMethod.POST)
public ModelAndView process(#RequestBody final String req)
{
//consumes = "text/plain"
System.out.println(req);
System.out.println(req);
return new ModelAndView("deneme");
}
https://spring.io/guides/gs/rest-service-cors/
So I wanted to know my web service's client's locale or ip etc.. How do I get it?
My endpoint method:
#POST
#Produces({MediaType.APPLICATION_JSON})
#Consumes({MediaType.APPLICATION_JSON})
#Path("/{EmployeeID}/Shifts/{ShiftID}/Confirm")
public Response confirmShift(#PathParam("EmployeeID")String employeeId, String params, #PathParam("ShiftID")String tbId);
How I get it in interceptor:
Map<String, List> headers = (Map<String, List>) message.get(Message.PROTOCOL_HEADERS);
I think protocol header must contain this info, I havn't checked it by the way. But how do I get it in web service.
Note: I want to avoid getting/setting stuff in cxf request context.
You need to inject MessageContext into your method, which contains HTTP servlet request.
For e.g.:
#POST
#Produces({MediaType.APPLICATION_JSON})
#Consumes({MediaType.APPLICATION_JSON})
#Path("/{EmployeeID}/Shifts/{ShiftID}/Confirm")
public Response confirmShift(#PathParam("EmployeeID") String employeeId,
String params,
#PathParam("ShiftID") String tbId,
#Context MessageContext context){
HttpServletRequest request = context.getHttpServletRequest();
String ip = request.getRemoteAddr();
/** ..... **/
}
Also there are some other ways of getting HTTP servlet request, one would be:
Message message = PhaseInterceptorChain.getCurrentMessage();
HttpServletRequest httpRequest = (HttpServletRequest) message.get(AbstractHTTPDestination.HTTP_REQUEST);
Hope this helps.
I'm trying to create automated, end to end, tests to my webapp by making rest calls (using retrofit). our rest calls are protected with spring security, so i have to login first.
To my best understanding, i need to call /j_spring_security_check with user/password, get the returned "Set-cookie" response header and set it as a "Cookie" request header on each rest call i perform.
It seems like my call to spring login "page" is successful as we have implemented an ApplicationListener which logs each successful login attempt,
however, the returned response from the call to j_spring_security_check has a status 200 (should be 302 as the apps redirects after successful login) and the body of the response is the login page itself.
What am i doing wrong?
the login retrofit interface:
#FormUrlEncoded
#POST("/j_spring_security_check")
Response basicLogin(#Field("user") String user, #Field("password") String pwd);
the code to call spring's login:
public static void login(String user, String pwd) {
PortalLoginService loginService = PortalRestAdapter.getInstance().createLoginService();
Response response = loginService.basicLogin(user, pwd);
String setCookieHeader = getSetCookieHeader(response.getHeaders());
AuthCookieInterceptor.getInstance().setSessionId(setCookieHeader);
}
private static String getSetCookieHeader(List<Header> headers) {
for (Header header : headers) {
if (SET_COOKIE_HEADER_NAME.equals(header.getName())) {
return header.getValue();
}
}
return null;
}
code of AuthCookieInterceptor intercpet method:
#Override
public void intercept(RequestFacade requestFacade) {
if (sessionId != null) {
requestFacade.addHeader("Cookie", sessionId);
}
}
the rest adapter init:
restAdapter = new RestAdapter.Builder()
.setRequestInterceptor(AuthCookieInterceptor.getInstance())
.setEndpoint(PORTAL_URL)
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
so basically I'm making a call to login, and setting the returned session id from the login response on each request i make after (using request interceptor)
Thanks a lot
You need to change the name of the parameters passed, j_spring_security_check is expecting j_username and j_password instead of your
Response basicLogin(#Field("user") String user, #Field("password") String pwd);
Also, because in the case of this call, the spring framework is returning us a html response (keep in mind that we are doing a POST to servlet), we need to set our converter, so you need to do something like this:
SimpleXMLConverter converter = new SimpleXMLConverter();
RestAdapter adapter = builder.setLogLevel(RestAdapter.LogLevel.FULL).setConverter(converter).build();
then a simple call like this one:
Response response = LoginClient.getService().login("john", "john1");
and from the response object, you can get any information you could need
I have solved this puzzle.
Frist of all to authorize user you need to replace "user" with "username"
#FormUrlEncoded
#POST("/login")
Response autorizeMethod(#Field("username") String user, #Field("password") String pwd);
then disable auto redirection in retrofit
val client=OkHttpClient.Builder().followRedirects(false).build()
Retrofit.Builder()
.baseUrl("http://localhost:8080")
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build()