#RequestMapping handling of special characters - java

I have a REST API
#RequestMapping(value = "/Save", method = RequestMethod.POST,
consumes = {"application/json;charset=ISO-8859-1" },
produces = {"application/json;charset=ISO-8859-1" })
public SaveResponse save(#RequestBody SaveRequest request) {
//some codes
}
}
My request contains the following lines
{
:
:
"mailingAddress": {
"addressLine1": "Carrera 36E N°",
"addressLine2": "Medellín, Antioquia",
"country": "COL"
}
:
And I received a 400 Bad Request
HTTP/1.1 400 Bad Request
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Date: Wed, 16 Jun 2021 12:26:37 GMT
Pragma: no-cache
Content-Length: 0
Expires: 0
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-RBT-Optimized-By: CANA014IJT (RiOS 6.1.1a #11) SC
And when I removed the characters "°" and "í" from the request, then the request can go through with no error. What is my problem?
Thank you.

You can try changing the character set from ISO-8859-1 to UTF-8, as the former does not support as wide an array of character mappings (What is the difference between UTF-8 and ISO-8859-1?).

Related

Token not needed after authorizing once

i am trying to implement token based authentication using JWT token. I am using JJWT library for that.
Here is my Security Configuration
#Override
protected void configure(HttpSecurity http) throws Exception {
//http.csrf().disable();
String[] patterns = new String[] {
"/login",
"/bower_components/**/*",
"/app/**/*",
"/index.html",
"/home.html",
"/signin.html"
};
http.authorizeRequests()
.antMatchers(patterns)
.permitAll()
.antMatchers("/**/*").hasAuthority("ROLE_USER")
.antMatchers("/*").hasAuthority("ROLE_USER")
.and()
.addFilterBefore(jwtAuthFilter, CsrfFilter.class)
.exceptionHandling()
.authenticationEntryPoint(jwtAuthEndPoint)
;
}
I am using springboot.
I called this api in the following way to generate a token.
curl -v -X POST "http://localhost:8080/login" -d '{"username":"greenrabbit948", "password":"celeste"}' --header "Content-Type: application/json" | jq .
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
> POST /login HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.43.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 51
>
} [51 bytes data]
* upload completely sent off: 51 out of 51 bytes
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Token: eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJqd3QtZGVtbyIsImV4cCI6MTQ2Nzc2Njk3MSwiaXNzIjoiaW4uc2RxYWxpLmp3dCJ9.eu_OuBIkc4BfcTsTu4t_6TCwyLkH4HcuQzvWIMzNQYdxXiWA77SfvwCe4mdc7C17mXdtBAsvFGDj7A9fzI0M1w
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Wed, 06 Jul 2016 06:02:51 GMT
{ [164 bytes data]
100 211 0 160 100 51 15071 4804 --:--:-- --:--:-- --:--:-- 16000
* Connection #0 to host localhost left intact
{
"username": "greenrabbit948",
"name": {
"title": "miss",
"first": "dionaura",
"last": "rodrigues"
},
"thumbnail": "https://randomuser.me/api/portraits/thumb/women/78.jpg"
}
Using the token i call the rest of my APIs,
Like this
curl -i -X POST "http://localhost:8080/login" -d '{"username":"greenrabbit948", "password":"celeste"}' --header "Content-Type: application/json"
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Token: eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJncmVlbnJhYmJpdDk0OCIsImV4cCI6MTQ2ODE0MDg1MiwiaXNzIjoiaW4uc2RxYWxpLmp3dCJ9.t9pqrOmYfaVkzuAQgo4D4VbN2PibQuHPuPA6RKYU-keTzbFAX58l77hQTc4Cq28HpjFOeiDvNpNEgilNHFOfVA
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sun, 10 Jul 2016 06:54:12 GMT
{"username":"greenrabbit948","name":{"title":"miss","first":"dionaura","last":"rodrigues"},"thumbnail":"https://randomuser.me/api/portraits/thumb/women/78.jpg"}
$ curl -s "http://localhost:8080/profile/details/yellowfrog347" --header "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJncmVlbnJhYmJpdDk0OCIsImV4cCI6MTQ2ODE0MDg1MiwiaXNzIjoiaW4uc2RxYWxpLmp3dCJ9.t9pqrOmYfaVkzuAQgo4D4VbN2PibQuHPuPA6RKYU-keTzbFAX58l77hQTc4Cq28HpjFOeiDvNpNEgilNHFOfVA" | jq .
{
"picture": {
"large": "https://randomuser.me/api/portraits/women/71.jpg",
"medium": "https://randomuser.me/api/portraits/med/women/71.jpg",
"thumbnail": "https://randomuser.me/api/portraits/thumb/women/71.jpg"
},
"name": {
"title": "ms",
"first": "sofia",
"last": "hansen"
},
"email": "sofia.hansen#example.com",
"username": "yellowfrog347"
}
Now whenever i call the same API which i have called before again without the Token, the data is shown. How can i stop this from happening? How to make the token compulsory so that the data is shown only when the token is present?
This happened when i used POSTMAN to call the APIs.
You can write function gettoken() which get the token.If token available return true otherwise false.hope you will get answer.
In-order to achieve this, you need implement an authorization framework like OAuth2 and add the following annotation
#PreAuthorize("#oauth2.hasScope('read') and #oauth2.hasScope('read')")
This will make sure only if the valid token is passed, client is able to access the service.

Java HttpURLConnection - enumerate all 302 redirect hops

my goal is to use java.net.HttpURLConnection in order to parse all the 302 redirect hops for a given URL.
This is my snippet code (I'm actually using it in Talend SW):
String url = row2.url;
java.net.HttpURLConnection con = (java.net.HttpURLConnection) new java.net.URL(url).openConnection();
con.setInstanceFollowRedirects(false);
con.connect();
String realURL = con.getHeaderField("Location");
System.out.println(realURL);
It works pretty well if there's only one 302 reply.
For instance if I populate row2.ulr= "https://jigsaw.w3.org/HTTP/300/302.html" the code will output -> https://jigsaw.w3.org/HTTP/300/Overview.html witch is 100% correct.
My problem is that I'm unable to parse several 302 reply, a typical example is the Facebook URL:
www.facebook.com/ID_account ->redirect-> www.facebook.com/ACCOUNT_NAME
Using a redirect checker online I found 2 - 302 response (I need the second one):
This is the CURL output:
> >>> http://www.facebook.com/123456789
>
> > --------------------------------------------
> > 302 Found
> > --------------------------------------------
>
> Status: 302 Found Code: 302
> Location: https://www.facebook.com/123456789 Vary: Accept-Encoding
> Content-Type: text/html; charset=UTF-8
> X-FB-Debug: Muf4PfCP9TRKCO17QUf7SV2vsdnrCu6Gw2+sjWAKe0QPGdAToJPcmgH5LHv3NIAhzsJXfPB3a9/mVtuhiiEihA==
> Date: Mon, 16 Oct 2017 16:02:55 GMT Connection: close
> Content-Length: 0
>
>
>
>
> >>> https://www.facebook.com/123456789
>
> > --------------------------------------------
> > 302 Found
> > --------------------------------------------
>
> Status: 302 Found Code: 302 X-XSS-Protection: 0
> public-key-pins-report-only: max-age=600;
> pin-sha256="WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=";
> pin-sha256="k2v657xBsOVe1PQRwOsHsw3bsGT2VzIqz5K+59sNQws=";
> pin-sha256="gMxWOrX4PMQesK9qFNbYBxjBfjUvlkn/vN1n+L9lE5E=";
> pin-sha256="q4PO2G2cbkZhZ82+JgmRUyGMoAeozA+BSXVXQWB8XWQ=";
> report-uri="http://reports.fb.com/hpkp/" Pragma: no-cache
> Location: https://www.facebook.com/a_name_account/
> Cache-Control: private, no-cache, no-store, must-revalidate
> X-Frame-Options: DENY Strict-Transport-Security: max-age=15552000;
> preload X-Content-Type-Options: nosniff Expires: Sat, 01 Jan 2000
> 00:00:00 GMT Vary: Accept-Encoding Content-Type: text/html;
> charset=UTF-8
> X-FB-Debug: j2KCBNZ1poIJ0xUeeQYbinpcqq2avoI4z8eWb9Dx/yUUg98uyGYGadydia7en1s5X4DJeaJB7VjxYaRvP+psCw==
> Date: Mon, 16 Oct 2017 16:02:55 GMT Connection: close
> Content-Length: 0
>
>
>
>
> >>> https://www.facebook.com/a_name_account/
Any suggestion on how to find the second 302 "Location" ->https://www.facebook.com/a_name_account/?
Thanks in advance
Regs
S.
This would be great behavior for a Recursive Method.
You could keep calling your method if you determine that there is still a location in the response header.
public void recurseLocation(String url) {
URL url = new URL(location);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setInstanceFollowRedirects(false);
connection.connect();
String newLocation = connection.getHeaderField("Location");
if (newLocation != null) {
newLocation = recurseLocation(newLocation);
} else {
newLocation = location;
}
return newLocation;
}

Apache Jmeter : Post an object not working with ModelAttribute

I am working on stress testing our webapplication written in Spring-MVC.
I would like to send an object Person to the application. I have added a system out to get the email, but whenever I am sending the object, it is null. What am I doing wrong?
Server code :
#RequestMapping(value = "/person/add", method = RequestMethod.POST)
public String addPerson(#ModelAttribute("person") Person person, BindingResult bindingResult) {
try {
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(person);
System.out.println("String is "+json);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("Person add called"+person.getUsername());
person.setUsername(this.stripHTML(person.getUsername()));
int personId = this.personService.addPerson(person);
if (!(personId == 0)) {
Person person1 = this.personService.getPersonById(personId);
Collection<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
Authentication authentication = new UsernamePasswordAuthenticationToken(person1, null, authorities);
SecurityContextHolder.getContext().setAuthentication(authentication);
return "redirect:/canvaslisting";
} else {
return "redirect:/";
}
}
Object sent in body data :
{"person":{"id":0,"username":"testemail#gmail.com","firstName":"test","cleanCacheFlag":false,"googleDrive":false,"dropbox":false,"evernoteConsumed":false,"statusChangeTimeStamp":null,"useCalendar":false,"newsletterFlag":false,"tourSteps":null,"profession":null,"notiz":null,"telePhone":null,"lastVisitedBoards":null,"leftGroup":null,"optionalEmail":null,"facebookLink":null,"xingLink":null,"linkedinLink":null,"lastOnlineTimestamp":null,"userRole":null,"homePage":null,"excelImportQuota":0,"toEmail":null,"code":null,"authorities":null,"role":null,"newpassword":null,"token":null,"profilePhotoString":null,"accountNonExpired":true,"credentialsNonExpired":true,"accountNonLocked":true,"active":true,"enabled":false}
}
Output :
Person add callednull
Screenshot :
Sample result
Thread Name: Thread Group 2-5
Sample Start: 2017-06-29 15:17:11 IST
Load time: 6
Connect Time: 0
Latency: 6
Size in bytes: 237
Sent bytes:0
Headers size in bytes: 205
Body size in bytes: 32
Sample Count: 1
Error Count: 1
Data type ("text"|"bin"|""): text
Response code: 415
Response message: Unsupported Media Type
Response headers:
HTTP/1.1 415 Unsupported Media Type
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Language: en
Content-Length: 1048
Date: Thu, 29 Jun 2017 09:47:11 GMT
Connection: close
HTTPSampleResult fields:
ContentType: text/html;charset=utf-8
DataEncoding: utf-8
Request:
POST http://127.0.0.1:8080/person/add/
POST data:
{"person":{"id":0,"username":"testemail#gmail.com","firstName":"test","cleanCacheFlag":false,"googleDrive":false,"dropbox":false,"evernoteConsumed":false,"statusChangeTimeStamp":null,"useCalendar":false,"newsletterFlag":false,"tourSteps":null,"profession":null,"notiz":null,"telePhone":null,"lastVisitedBoards":null,"leftGroup":null,"optionalEmail":null,"facebookLink":null,"xingLink":null,"linkedinLink":null,"lastOnlineTimestamp":null,"userRole":null,"homePage":null,"excelImportQuota":0,"toEmail":null,"code":null,"authorities":null,"role":null,"newpassword":null,"token":null,"profilePhotoString":null,"accountNonExpired":true,"credentialsNonExpired":true,"accountNonLocked":true,"active":true,"enabled":false}
}
[no cookies]
Request Headers:
Connection: close
Content-Length: 717
Content-Type: application/x-www-form-urlencoded
Change header Content-Type in HTTP Header Manager from:
Content-Type: application/x-www-form-urlencoded
To:
Content-Type: application/json
Shouldn't you just have an #RequestBody annotation on person ?
public String addPerson(#RequestBody Person person);
Well, there is a typo or copy-paste issue in your JMeter request
Also your JMeter configuration might be missing HTTP Header Manager configured to send Content-Type header with the value of application/json

Angular2 - unable to get Set-Cookie from auth. response (jaas, wf)

Iam trying to authenticate from Angular2.1.0 to JAAS form-based j2ee app on WildFly 8.2
let j_username = 'sb2';
let j_password = 'sb222';
let url: string = 'http://127.0.0.1:8888/prototype-rest/j_security_check';
let body = 'j_username=' + j_username + '&j_password=' + j_password;
let headers = new Headers({
'Content-Type': 'application/x-www-form-urlencoded'
})
;
//let options = new RequestOptions({headers: headers, withCredentials : true});
let options = new RequestOptions({headers: headers});
this.http.post(url, body, options)
.subscribe(
(res: Response) => {
console.log('res = ' + res);
console.log(res.headers.keys());
var headers = res.headers;
var setCookieHeader = headers.get('Set-Cookie');
console.log('setCookieHeader = ' + setCookieHeader);
},
err => {
console.log('err = ' + err);
}
)
;
response from wildfly
HTTP/1.1 200 OK
Expires: 0
Cache-Control: no-cache, no-store, must-revalidate
X-Powered-By: Undertow/1
Set-Cookie: JSESSIONID=iyD6Yz_Tj7xsIM1zRDHaR2bh.sk-za-04702; path=/prototype-rest
Access-Control-Allow-Headers: accept, authorization, content-type, x-requested-with
Server: WildFly/8
Pragma: no-cache
Access-Control-Expose-Headers: Set-Cookie
Date: Thu, 03 Nov 2016 14:01:41 GMT
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Content-Length: 0
Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT
Access-Control-Max-Age: 3600
My problem is that I am not able to read Set-Cookie, if I use withCredentials : true (I am not sure if I should), response fails ... I'd like to add JSESSIONID to request, where I register websocket ...

Jersey can't add parameter when post submit

I'm using Jersey 2.4.1
I dont know. Why i can't add parameter when post submit.
Parameter information should print at line number 5 in my think.
my sample code is below
#Test
public void test() {
Client client = ClientBuilder.newClient();
client.register(new LoggingFilter());
WebTarget target = client.target("http://stackoverflow.com/");
Form form = new Form();
form.param("x", "foo");
form.param("y", "bar");
target.request(MediaType.APPLICATION_JSON_TYPE)
.post(Entity.form(form));
}
result logging is..
1 * LoggingFilter - Request received on thread main
1 > POST http://stackoverflow.com/
1 > Accept: application/json
1 > Content-Type: application/x-www-form-urlencoded
2 * LoggingFilter - Response received on thread main
2 < 200
2 < X-Frame-Options: SAMEORIGIN
2 < Date: Mon, 02 Dec 2013 14:13:35 GMT
2 < Vary: *
2 < Content-Length: 195990
2 < Expires: Mon, 02 Dec 2013 14:14:35 GMT
2 < Last-Modified: Mon, 02 Dec 2013 14:13:35 GMT
2 < Content-Type: text/html; charset=utf-8
2 < Pragma: no-cache
2 < Cache-Control: public, max-age=60
To print form parameters to console log you need to instantiate LoggingFilter using other constructor than the default one, see LoggingFilter(java.util.logging.Logger, boolean):
client.register(new LoggingFilter(Logger.getAnonymousLogger(), true));
This behavior might be different from the one present in Jersey 1.x.

Categories