Alfresco login api giving Bad Request 400 - ajax

I am trying to login to alfresco through api. I do not know why it is returning error 400 Bad Request.
The json should be correct and in my ajax call I have also set the content type to 'application/json'.
This is my ajax call.
var jsonData = JSON.stringify({ username : usernameV, password : passwordV });
var request = $.ajax({
settings : {contentType:'application/json'},
type: "POST",
url: "http://---ip---/alfresco/service/api/login",
data: jsonData
});
The json string in the console.
{"username":"admin","password":"admin1"}
Error
400 Bad Request
Request sent by the client was syntactically incorrect
Message in responseJSON object
Unable to parse JSON POST body: A JSONObject text must begin with '{' at character 0"

I suspect this is to do with the way you are setting the contentType as the only ways for this to occur appear to either be empty JSON or an incorrect contentType. Try:
var request = $.ajax({
contentType:"application/json",
type: "POST",
url: "http://---ip---/alfresco/service/api/login",
data: jsonData
});

I have created one java program which was doing same thing.I think you should pass username and password in url.Even if you directly hit below url in browser, It will give you alf_ticket, which is use full in authentication for alfresco.
private static String getAlfticket() throws IOException, JSONException {
String ticket = "";
URL url = new URL("http://hostname/alfresco/service/api/login u="+USERNAME+"&pw="+PASSWORD+"&format=json");
URLConnection con = url.openConnection();
InputStream in = con.getInputStream();
String encoding = con.getContentEncoding();
encoding = encoding == null ? "UTF-8" : encoding;
String json = IOUtils.toString(in, encoding);
JSONObject getData = new JSONObject(json);
System.out.println(getData.getJSONObject("data").get("ticket")
.toString());
ticket =getData.getJSONObject("data").get("ticket").toString();
return ticket;
}
Krutik Jayswal
Alfresco Developer

Related

Angular6 File Upload (Image) with Spring boot

I have a problem when uploading an image in angular 6.
Angular:
addAvatar(username: string, file: File) {
const headers = new HttpHeaders({
});
const formData: FormData = new FormData();
formData.append('file', file, file.name);
return this.http.post(`${this.API_URL}/addavatar/` + username, formData, {headers});
}
Spring controller:
#PostMapping("/addavatar/{username}")
public ResponseEntity<?> addAvatar(#PathVariable(value = "username") String username, #RequestPart(name = "file", required = false) MultipartFile file) {
return userService.addAvatar(username, file);
}
If I send request in Postman all works, but if I want to send request in Angular then I have a 404.
File Upload in Postman
Response in html
/file/ URI in Postman URL seems to be overlooked at Angular request path literal API_URL. That's why it occurs the 404 error.

form data is not getting posted to spring controller

Form data:
form dat from UI developer tools
user.username:SS
user.email:SGFG#GMAIL.COM
user.firstName:WWW
user.lastName:FF
ext-gen1170:ENV_DEV
ext-gen1171:false
ext-gen1172:false
user.password:
userGroupPermissions:[{"userName":"SS","groupName":"ENV_DEV","permission":"*"}]
Web.xml for the dispatcher servlet:
<servlet-mapping>
<servlet-name>user</servlet-name>
<url-pattern>/spring/</url-pattern>
</servlet-mapping>
Controller:
#RequestMapping(value ="/createUser/", method = RequestMethod.POST)
#Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
#ResponseBody
public String createUser(#RequestParam(value = "user.username", required = true) String username,
#RequestParam(value = "user.email", required = true) String email,
#RequestParam(value = "user.firstName", required = true) String firstName,
#RequestParam(value = "user.lastName", required = true) String lastName,
#RequestParam(value = "userGroupPermissions", required = true) UserGroupPermission userGroupPermissions,
#RequestParam(value = "password", required = false) String password) throws IOException {
Above details will be added to handle the request
There are no errors in console but the breakpoint is not hit when I keep the break point in controller.
I am getting 404 for this code.
Extjs:
var url = '/spring/createUser';
There are two ways to resolve this -- change the way you are sending parameters to Java or change the way you are receiving parameters.
Just change Java
To keep things simple you should change Java.
GET requests should use #RequestParam arguments in Spring controllers in a way you specified.
POST/PUT requests should use #RequestBody argument in Spring controllers.
So the Spring controller should look like this:
#RequestMapping(value ="/createUser/", method = RequestMethod.POST)
#ResponseBody
public String createUser(#RequestBody UserParams params)
Obviously if you need the #Transactional part you should also leave it.
Sending various requests with ExtJS
Here are some examples on how to use Ext.Ajax.request to send various types of requests.
I've used Polish in values so you can also see how encoding of UTF-8 text works.
Query string
Sending in query string means things get encoded directly in URL after ?. E.g. /test?firstName=Imi%C4%99&lastName=Nazwisko.
// (Java/Spring can get this with `#RequestParam`)
Ext.Ajax.request({
url: '/test',
method: 'GET',
params: {
firstName: 'Imię',
lastName: 'Nazwisko'
}
});
Form data
This is used when sending forms in a standard way. Things get encoded in the body of the request, but the format is actually the same as for the query string (e.g. firstName=Imi%C4%99&lastName=Nazwisko).
// (Java/Spring can get this with `#RequestBody`)
Ext.Ajax.request({
url: '/test',
method: 'PUT',
params: {
firstName: 'Imię',
lastName: 'Nazwisko'
}
});
Request payload
This is a JSON communication. Things get encoded in the body of the request, but in a JSON format (e.g. {"firstName":"Imi\u0119","lastName":"Nazwisko"}).
// (Java/Spring can get this with `#RequestBody`)
Ext.Ajax.request({
url: '/test',
method: 'PUT',
jsonData: {
firstName: 'Imię',
lastName: 'Nazwisko'
}
});
Query string in PUT/POST request
You can trick ExtJS to pass parameters in the URL rather then request body. When both params and jsonData are present in the Ext.Ajax.request one of them has to be put in the URL.
So to pass params in the query string use this:
Ext.Ajax.request({
url: '/test',
method: 'PUT',
params: {
firstName: 'Imię',
lastName: 'Nazwisko'
},
jsonData: {}
});
Note the empty jsonData. This will be encoded in request body as {} and can simply be omitted on the receiving end. In this case Java/Spring.
So this way you would receive all params as #RequestParam arguments in your Spring controller.

How to parameterize Bearer token authorization in Jmeter

I have a jmeter login script where user logs in and logs out. The detailed screenshots are attached below.
Request data is as attached:
In the response date , the authorization token is generated:
And the regular expression for the same is as below:
I am passing the value as parameter in 55/users:
When I'm running the script it is failing:
Here is the response data:
Use Header Manager to pass the Token as a Header so you would have:
See for more details:
https://stackoverflow.com/a/43283700/460802
If you're looking to learn jmeter correctly, this book will help you.
A bit easier JMeter setup (login/get):
Thread Group
HTTP Request, Body Data: { "Login":"some", "Password":"credentials" }
HTTP Header Manager: content-type application/json
JSON Extractor - Names of created variables: Token; JSON Path expression: tokenName (root level in my case)
HTTP Request
HTTP Header Manager: content-type -> application/json; Authorization -> Bearer ${Token}
Response Assertion: Fields to Test = Response Code; Pattern Matching Rules = Equals, Not; Pattern to Test 401
View Results Tree to check results
Local IE Ajax version in case...
<SCRIPT>
var baseUri = 'https://localhost:port';
var tokenUri = '/something';
var getUri = '/restrictedData';
var token;
var form = { "Login":"some", "Password":"credentials" };
postRequest(baseUri + tokenUri, form, gotToken)
function gotToken(progress) {
var response = progress.srcElement;
if (response.status != 200) {
document.body.innerText = "Error:\n" + response.response;
return;
}
token = JSON.parse(response.response);
console.log(JSON.stringify(token));
var restricted = getRequest(baseUri + getUri, token.tokenName, gotRestricted);
}
function gotRestricted(progress) {
var jsonStr = progress.srcElement.response;
var jsonObj = JSON.parse(jsonStr);
document.body.innerText = JSON.stringify(token,null,2) + '\n\n' + JSON.stringify(jsonObj,null,2);
}
function getRequest(url, token, callback) {
var xhr = new XMLHttpRequest();
xhr.onloadend = callback;
xhr.open('GET', url);
xhr.setRequestHeader('contentType', 'application/json')
if (token) xhr.setRequestHeader("Authorization", "Bearer " + token);
xhr.send();
return xhr;
}
function postRequest(url, body, callback) {
var xhr = new XMLHttpRequest();
xhr.onloadend = callback;
xhr.open('POST', url);
xhr.setRequestHeader('Content-Type', 'application/json')
xhr.send(JSON.stringify(body));
return xhr;
}
</SCRIPT>
Add Bearer ${token} in HTTP Header Manager available under failing HTTP Request.
If you already have the bearer token and just want to use in in header manager then,
in HTTP HEADER MANAGER tab, put these values under NAME and VALUE column respectively.
Name: Authorization
Value: Bearer "add your actual token without quotes"
Once you've extracted the token from the token API request, use this token in the HTTP Authorization Header manager for subsequent API's. Example below:
Header Name: Header Value Authorization: Bearer ${generated_token}
Where "generated_token" is a variable containing the extracted token.
I got cUrl from my API and then I imported it.
use Authorization as parameter name and value should be
Bearer ${variable_name}

Oracle MAF-MCS API call

I have created a custom POST api for getting login information in MCS. when i check in SOAPUI it works perfectly fine. the parameters passed are
1. header
Oracle-Mobile-Backend-Id: ********************
2. Authentocation
Username:****************
password: **************
and basic login info username and password as "User1" and "user1" respectively.
Step2:
when i call the API from MAF i am getting an error 400
the post method used is
public static Response callPost(String restURI, String jsonRequest) {
String responseJson = "";
Response response = new Response();
RestServiceAdapter restServiceAdapter = Model.createRestServiceAdapter();
restServiceAdapter.clearRequestProperties();
//restServiceAdapter.setConnectionName("MiddlewareAPI");
// restServiceAdapter.setConnectionName("");
restServiceAdapter.setRequestType(RestServiceAdapter.REQUEST_TYPE_POST);
restServiceAdapter.addRequestProperty("Content-Type", "application/json");
restServiceAdapter.addRequestProperty("Accept", "application/json; charset=UTF-8");
restServiceAdapter.addRequestProperty("Oracle-Mobile-Backend-Id", "**********");
restServiceAdapter.addRequestProperty("Domain", "mcsdem0001");
restServiceAdapter.addRequestProperty("Username", "******");
restServiceAdapter.addRequestProperty("Password", "*****");
//restServiceAdapter.addRequestProperty("Authorization", "Basic "+new String(encodedBytes));
System.out.println("**** Authorization String ****=>"+new String(encodedBytes));
System.out.println("**** RestURI ******=>"+restURI);
System.out.println("**** jsonRequest ******=>"+jsonRequest);
restServiceAdapter.setRequestURI(restURI);
restServiceAdapter.setRetryLimit(0);
try {
responseJson = restServiceAdapter.send(jsonRequest);
int responseCode = restServiceAdapter.getResponseStatus();
response.setResponseCode(responseCode);
response.setResponseMessage(responseJson);
response.setHeader(restServiceAdapter.getResponseHeaders());
} catch (Exception e) {
int responseCode = restServiceAdapter.getResponseStatus();
response.setResponseCode(responseCode);
response.setResponseMessage(responseJson);
}
System.out.println("Response:" + responseJson);
return response;
}
Could anyone please tell me is there any error in the post method??
This can be due to the version conflict. Try to use HttpUrlConnection instead of RestServiceAdapter and let me know if it works.
actually this bit
restServiceAdapter.addRequestProperty("Username", "******");
restServiceAdapter.addRequestProperty("Password", "*****");
doesn't work because you attempt to pass username and password as a HTTP header. Instead it should be passed as you were trying here
restServiceAdapter.addRequestProperty("Authorization", "Basic "+new String(encodedBytes));
However, these should not be encoded bytes but a base64 encoded string in the form
Basis (without the < abd >)
Note that user identity domains only need to be provided in multi-tenant environments. In MCS, the user domain is defined through the mobile backend you connect to.
Frank
Use the MAF MCS Utility library to make it allot easier.
The developer guide can be found here: http://download.oracle.com/otn_hosted_doc/maf/mafmcsutility-api-doc-082015.pdf
Example code:
MBEConfiguration mbeConfiguration =
new MBEConfiguration(
<mbe rest connection>,<mobileBackendId>,
<anonymous key string>,<application key string>,
MBEConfiguration.AuthenticationType.BASIC_AUTH);
mbeConfiguration.setEnableAnalytics(true);
mbeConfiguration.setLoggingEnabled(false)
mbeConfiguration.setMobileDeviceId(
DeviceManagerFactory.getDeviceManager().getName());
MBE mobileBackend = MBEManager.getManager().
createOrRenewMobileBackend(<mobile backend Id>, mbeConfiguration);
CustomAPI customApiProxy = mbe.getServiceProxyCustomApi();
MCSRequest request = new MCSRequest(mobileBackend.getMbeConfiguration());
request.setConnectionName(<Rest connection name>);
request.setRequestURI("/moile/custom/mockup/employees");
request.setHttpMethod(MCSRequest.HttpMethod.POST);
request.setPayload("{\"id\":\"1\"\"name\":\"nimphius\",\"firstName\":\"frank\"}");
request.setRetryLimit(0);
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type","application/json");
request.setHttpHeaders(headers);
MCSResponse response = customApiProxy .sendForStringResponse(request);
String jsonResponse = (String) response.getMessage();

Figuring out who has authenticated with basicAuth on Node while processing a POST request

I am using basicAuth to authenticate POSTs on a specific address.
On the client side I am using a command of the form:
$.ajax({
type: "POST",
accepts: "text/plain",
url: "http://localhost:3000/somewhere",
data: JSON.stringify(something),
contentType: "application/json; charset=UTF-8",
dataType: "json",
success: function(data) {
window.alert("Received back: '" + data + "'");
},
username: theUsername,
password: "a password"
});
This is working fine, in the sense that the username stored in theUsername passes the authentication mechanism that I have on node. While the user is authenticated I can print a console.log statement and see who has actually authenticated (I am not validating the password at the moment). But then the actual processing starts for the POST request. However, at that point how can I figure out the username and the password used in the original request? I tried to look on the headers of the request but I don't see anything there.
When you receive a Basic authentication request you should be able to read the "authorization" header in req.headers.authorization You have to pull out the the base64 encoded credentials and then decode them. Presumably, in Express you use req.header("authorization") or req.get("authorization")
For a standalone example, take a look at https://gist.github.com/charlesdaniel/1686663 which I have copied underneath for future reference
var http = require('http');
var server = http.createServer(function(req, res) {
// console.log(req); // debug dump the request
// If they pass in a basic auth credential it'll be in a header called "Authorization" (note NodeJS lowercases the names of headers in its request object)
var auth = req.headers['authorization']; // auth is in base64(username:password) so we need to decode the base64
console.log("Authorization Header is: ", auth);
if(!auth) { // No Authorization header was passed in so it's the first time the browser hit us
// Sending a 401 will require authentication, we need to send the 'WWW-Authenticate' to tell them the sort of authentication to use
// Basic auth is quite literally the easiest and least secure, it simply gives back base64( username + ":" + password ) from the browser
res.statusCode = 401;
res.setHeader('WWW-Authenticate', 'Basic realm="Secure Area"');
res.end('<html><body>Need some creds son</body></html>');
}
else if(auth) { // The Authorization was passed in so now we validate it
var tmp = auth.split(' '); // Split on a space, the original auth looks like "Basic Y2hhcmxlczoxMjM0NQ==" and we need the 2nd part
var buf = new Buffer(tmp[1], 'base64'); // create a buffer and tell it the data coming in is base64
var plain_auth = buf.toString(); // read it back out as a string
console.log("Decoded Authorization ", plain_auth);
// At this point plain_auth = "username:password"
var creds = plain_auth.split(':'); // split on a ':'
var username = creds[0];
var password = creds[1];
if((username == 'hack') && (password == 'thegibson')) { // Is the username/password correct?
res.statusCode = 200; // OK
res.end('<html><body>Congratulations you just hax0rd teh Gibson!</body></html>');
}
else {
res.statusCode = 401; // Force them to retry authentication
res.setHeader('WWW-Authenticate', 'Basic realm="Secure Area"');
// res.statusCode = 403; // or alternatively just reject them altogether with a 403 Forbidden
res.end('<html><body>You shall not pass</body></html>');
}
}
});
server.listen(5000, function() { console.log("Server Listening on http://localhost:5000/"); });

Resources