on 11-02-2014 4:11 PM
Hi everybody,
I'm trying to make a CREATE-Request to SAP Netweaver Gateway.
The frontend program is and android application which is using the odata4j library.
When I call the CREATE-Request I always got the error "Validation of CSRF-Token failed"... so I searched a bit and found that you need to fetch the CSRF-Token first and put it as a separate header.
The coding seems to work and looks like the following:
public class SAPCSRFBehavior implements JerseyClientBehavior {
private String xcsrfToken = "";
@Override
public ODataClientRequest transform(ODataClientRequest request) {
if(request.getMethod().equals("GET")){
request = request.header("X-CSRF-Token", "Fetch");
return request;
}else{
request = request.header("X-CSRF-Token", this.xcsrfToken);
return request;
}
}
@Override
public void modify(ClientConfig arg0) {
// TODO Auto-generated method stub
}
@Override
public void modifyClientFilters(Filterable client) {
client.addFilter(new ClientFilter(){
@Override
public ClientResponse handle(ClientRequest clientRequest)
throws ClientHandlerException {
ClientResponse response = this.getNext().handle(clientRequest);
MultivaluedMap<String, String> headers = response.getHeaders();
xcsrfToken = headers.getFirst("X-CSRF-Token");
System.out.println("Token: " + xcsrfToken);
return response;
}
});
}
@Override
public void modifyWebResourceFilters(Filterable arg0) {
// TODO Auto-generated method stub
}
}
When I log the Token I'll get a valid value for it ... but ... somehow I simply get the same error message as before
I really hope somebody has a solution for the problem ... Looking really forward to hearing from you!
Greetings
Stef
Some news:
I tried it again and found out that somehow in the POST request the CSRF-Token is not sent. When I look at the console I always get as value "required" ...
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I can finally do PUT (update) and CREATE Operations to SAP Netweaver Gateway from Android native app using odata4j:
I solved my problem following this SAP SCN thread:
SAP Fiori LL16 - http 403 Forbidden CSRF token error
After that, I put these headers at ODataClientRequest:
request = request.header("X-Requested-With", "XMLHttpRequest")
.header("Authorization", "Basic " + encoded);
Then, you don't need to implement any SAPCSRFBehaviour class that gets the csrf token from GET requests. Only with that two headers is enough.
With this configuration I didn't receive again the 403 Forbidden error.
Hope this can help anyone.
Carlos.
Hi Carlos,
Can you provide the sample code for your POST and PUT request?
I did what you mentioned with regards to disabled CSRF token, but I still got 403 from Android.
I also tested the same payload, request method and it works on REST client, can you shed some light on what's missing on my implementation?
Hi Ginwene,
Here is the commented code, hope it helps you:
ODataJerseyConsumer consumer = ODataJerseyConsumer.create(serviceUrl);
ODataJerseyConsumer.Builder builder = ODataJerseyConsumer.newBuilder(serviceUrl);
// Authentication
builder.setClientBehaviors(new OClientBehavior(){
@Override
public ODataClientRequest transform(ODataClientRequest request) {
String userPassword = "USEREXAMPLE" + ":" + "passexample";
String encoded = Base64.encodeBase64String(userPassword.getBytes());
encoded = encoded.replaceAll("\r\n?", "");
// Necessary headers to do PUT and POST operations
request = request.header("X-Requested-With", "XMLHttpRequest")
.header("Authorization", "Basic " + encoded);
return request;
}});
consumer = builder.build();
// LOG HTTP
consumer.dump.all(true);
// CREATE ENTITY
consumer.createEntity("matrset")
.properties(OProperties.string("Material", "30"))
.properties(OProperties.string("MatlDesc", "Nuevo Material Android 3"))
.properties(OProperties.string("Langu", "S"))
.properties(OProperties.string("IndSector", "C"))
.properties(OProperties.string("MatlType", "ZSTD"))
.properties(OProperties.string("MatlGroup", "1130"))
.properties(OProperties.string("BaseUom", "KG")).execute();
// UPDATE ENTITY
OEntity entityToUpdate = consumer.getEntity("matrset", "35").execute();
// UPDATE ENTITY OPERATION (PUT)
consumer.updateEntity(entityToUpdate).properties(OProperties.string("MatlDesc","Descripcion Nueva de Material 2"))
.properties(OProperties.string("Langu","S")).execute();
Hi Carlos,
Here's my application code:
ODataJerseyConsumer consumer = ODataJerseyConsumer.create(SERVICE_URL);
ODataJerseyConsumer.Builder builder = ODataJerseyConsumer.newBuilder(SERVICE_URL);
// Basic Authentication Consumer
builder.setClientBehaviors(new OClientBehavior() {
@Override
public ODataClientRequest transform(ODataClientRequest oRequest) {
String userPassword = "USER" + ":" + "PASSWORD";
String encoded = Base64.encodeBase64String(userPassword.getBytes());
encoded = encoded.replaceAll("\r\n?", "");
oRequest = oRequest
.header("X-Request-With", "XMLHttpRequest")
.header("Content-Type", "application/atom+xml;type=entry")
.header("Authorization", "Basic " + encoded);
return oRequest;
}
});
consumer = builder.build();
// Outputs all http request
consumer.dump.all(true);
// POST and no identifier since new user account
consumer.createEntity("UserProfileSet")
.properties(OProperties.string("ProfileCode", "EXECUTIVE"))
.properties(OProperties.string("User", "MY_EMAIL"))
.execute();
I'm using 0.7 odata4j, inside an asyncTask for background processing and running in an emulator.
All GET method are working, except for POST and PUT.
Thanks,
Gin
After testing around a bit and setting some messages in the console it seems that the token isn't set for the POST request???? ....
I also read something about setting special CookieValues ... but I don't have a cookie.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hey Krishna,
thx for your reply! I've already found this blog post and did exactly the same ... the problem which I have is that I don't have any cookies available at the response and also not at the request ... I receive the CSRF-Token but it seems that it isn't sent with the CREATE-request.
I've tried to test it yeah ... but it is not quite easy to teast a CREATE-request with a browser tool or is there a specifig possibility???
Greetings
Stef
Well what I did so far was to test a GET and a POST request ... and it actually seemed to work because I took the token from the GET request and set it as a x-csrf-token header in the POST request --> the error message "validation of csrf failed" disappeared.
But when I test it with odata4j ... the error message is still there
User | Count |
---|---|
84 | |
10 | |
10 | |
9 | |
7 | |
6 | |
5 | |
5 | |
4 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.