I am using ballerina and I want to connect with WSO2 identity server for authentication.
I am not able to add Basic Authorization using wso2/soap.
Can someone provide an example?
xml body = xml `<tes:insert_employee_operation xmlns:tes="http://teste.cv">
<tes:name>{{username}}</tes:name>
<tes:age>10</tes:age>
<tes:ssn>25</tes:ssn>
</tes:insert_employee_operation>`;
soap:SoapRequest soapRequest = {
soapAction: "urn:insert_employee_operation",
payload: body
};
io:println(soapRequest);
var details = soapClient->sendReceive("/services/EmployeeService", soapRequest);
match details {
soap:SoapResponse soapResponse => {
io:println(soapResponse);
xml respostaXml = soapResponse.payload;
json respostaJson = respostaXml.toJSON({});
response.setJsonPayload(respostaJson);
_=caller->respond(response);
}
soap:SoapError soapError => io:println(soapError);
}
code
There are more fields available in the soap:SoapRequst object. See https://central.ballerina.io/wso2/soap#SoapRequest.
If you meant ws-security then can use as follows:
soap:SoapRequest soapRequest = {
soapAction: "urn:insert_employee_operation",
payload: body,
username: "foo",
password: "bar"
};
You can also set soap envelop headers using the headers field.
You can add basic authorization under the client endpoint configuration.
endpoint soap:Client soapClient {
clientConfig: {
url: "http://localhost:9000",
auth: {
scheme: http:BASIC_AUTH,
username: "is_username",
password: "is_password"
}
}
};
This will add the Authorization header into the HTTP request. The complete code will look as follows:
import ballerina/http;
import ballerina/io;
import ballerina/log;
import wso2/soap;
endpoint soap:Client soapClient {
clientConfig: {
url: "http://localhost:9000",
auth: {
scheme: http:BASIC_AUTH,
username: "is_username",
password: "is_password"
}
}
};
public function main(string... args) {
xml body = xml `<tes:insert_employee_operation xmlns:tes="http://teste.cv">
<tes:name>{{username}}</tes:name>
<tes:age>10</tes:age>
<tes:ssn>25</tes:ssn>
</tes:insert_employee_operation>`;
soap:SoapRequest soapRequest = {
soapAction: "urn:insert_employee_operation",
payload: body
};
io:println(soapRequest);
var details = soapClient->sendReceive("/services/EmployeeService", soapRequest);
match details {
soap:SoapResponse soapResponse => {
io:println(soapResponse);
xml respostaXml = soapResponse.payload;
json respostaJson = respostaXml.toJSON({});
response.setJsonPayload(respostaJson);
_ = caller->respond(response);
}
soap:SoapError soapError => io:println(soapError);
}
}
Related
I'm trying to make HTTP POST request to consume Mailchimp API (From Angular7 code)
but i'm getting this response:
Access to XMLHttpRequest at 'https://us12.api.mailchimp.com/3.0/lists/ddddddd/members' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
From REST client i'm able to make insert in Mailchimp without having this CROS issue
export class MyService {
constructor(public httpRequestsService: HttpRequestsService) { }
private async getHttpHeader() {
const rheaders = new HttpHeaders({
'Content-Type': 'application/json' ,
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
'Access-Control-Allow-Headers':'X-Requested-With',
'Authorization': 'apikey ' + MailchimpSettings.API_KEY
});
return { headers: rheaders };
}
public async AddNewMember(email: string, language = 'en', status = , mergeFields?: any) {
var url = MailchimpSettings.URL;
var body = {
"email_address": email,
"status": MailchimpSettings.SUBSCRIBED_STATUS,
"language": language
};
var httpOptions = await this.getHttpHeader();
var _body = JSON.stringify(body);
var result = await this.post(url, _body, httpOptions);
}
public async post(url: string, body: string | {} = {}, requestHeaders?: any): Promise<Response> {
return this.http.post(url, body, requestHeaders).toPromise()
.then((res: any) => {
return res;
})
.catch((err) => {
return this.handleErrorPromise(err);
});
}
}
Anyone who can help me with right HTTP headers (or any required change) to reproduce exactly REST client behavior and be able to make a successful POST.
Thanks for your help
Unfortunately, the answer is you can't. Mailchimp does not support CORS because that would require passing API credentials, and that is not secure.
The option is to make requests from another server like you mentioned from the REST client or make a custom signup form that will use more restricted API call.
Or use jsonp request for mailchimp form clients.
See this
I'm currently building out an Angular 7 App, and trying to implement the following HTTP API Call Scenario:
Request for an Application Token:
https://(URL)/token
Request Type: POST
Headers:
Accept: application/json
Request Body: empty
I have a Service class in the Angular app and the code is as follows:
import { HttpClient } from '#angular/common/http';
import { HttpHeaders } from '#angular/common/http';
The requestToken function is implemented as follows:
requestToken() {
let headers = new HttpHeaders();
headers = headers.set('Accept', 'application/json');
return this.http.post(this.configUrl + '/token', headers);
}
The Service is then called in one of the components in the App:-
getToken() {
this.service.requestToken().subscribe( res => {
console.log(res);
}, error => {
console.log(error);
});
}
When I run the App, I get a 404 Not Found error in the console. I used Postman to make an API call, setting the 'Accept' header to 'application/json' and then specifying url as https://(URL)/token and I successfully get a response. But I'm unable to make it work via Angular.
Is there something else I need to do to set the header properly in Angular? Also, I have no way to check if CORS has been enabled on the API server as this is a third-party service which I'm trying to call.
Any help would be appreciated. Thanks
Solved the problem. Changed the POST call to the following:
requestToken() {
const httpHeaders = new HttpHeaders({
'Accept': 'application/json'
});
return this.http.post(this.configUrl + '/token', { body: ''}, { headers: httpHeaders });
}
Had to add an empty 'body' parameter
I am busy with a small web app where I am trying to post to a API using a RestService but keep getting a 400 bad request. When I do the exact same post using the Insomnia Rest client I get a 200 Ok... Any idea what i'm doing wrong/what I can look at to find out what's going on?
Update:
It turns out the issue is a incorrect header, there's still a unresolved error i'm getting when trying to add the correct header...
Question continuation link Here
My error:
http://10.60.160.34/BRMServices/WebEnquiry/StockTake/AddToStockTake Failed to load resource: the server responded with a status of 400 (Bad Request)
stockTake:1 XMLHttpRequest cannot load http://10.60.160.34/BRMServices/WebEnquiry/StockTake/AddToStockTake. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 400.
main.bundle.js:47711 failure: server error
My code:
stock-take.component.ts:
import { Component, OnInit } from '#angular/core';
import { FormBuilder, FormGroup, Validators } from '#angular/forms';
import { RestService } from '../../services/rest.service';
import { StockTakeModel } from '../../models/stock-take.model';
#Component({
selector: 'stock-take',
templateUrl: './stock-take.component.html',
styleUrls: ['./stock-take.component.css']
})
export class StockTakeComponent implements OnInit {
stockTakeForm: FormGroup;
stockTakeModel: StockTakeModel;
constructor(private fb: FormBuilder, private restService: RestService) {
this.stockTakeForm = fb.group({
'SheetNo':['', Validators.required],
'BinNo':['', Validators.required],
'BarCode':['', Validators.required],
'Quantity':['', Validators.required]
});
}
doStockTake(val: any) {
//console.log("val:" + JSON.stringify(val));
//this.stockTakeModel = new StockTakeModel(0, 0, val[Object.keys(val)[2] '', val[Object.keys(val)[0]], val[Object.keys(val)[1]], val[Object.keys(val)[3]], 0);
this.stockTakeModel = val;
this.stockTakeModel.StockTakeID = '0';
this.stockTakeModel.IDKey = '0';
this.stockTakeModel.ProductCode = '';
this.stockTakeModel.PackSize = '0';
console.log(this.stockTakeModel);
console.log(JSON.stringify(this.stockTakeModel));
this.submitStockTake(this.stockTakeModel);
}
submitStockTake(stockTakeModel: StockTakeModel) {
//console.log(stockTakeModel);
this.restService.postStockTake(stockTakeModel)
.subscribe(
(res) => {
console.log(res);
},
(res) => {
console.log("failure: " + res);
}
);
this.stockTakeForm.reset();
}
ngOnInit() {
}
}
submitStockTake function from rest.service.ts:
postStockTake(stockTakeModel: StockTakeModel) : Observable<Response> {
console.log(JSON.stringify(stockTakeModel));
return this.http.post(this.API_URL + "StockTake/AddToStockTake", JSON.stringify(stockTakeModel), this.headers)
.map((res: Response) => res.json())
.catch((error: any) => Observable.throw(error.json().error || 'server error'));
}
That indicates that you are not quite posting the same thing both ways - perhaps different request headers? Perhpas the browser running RestClient has authenticated? Inspect the actual requests in the network tab and check URL, headers, authentication etc - something has to be different.
Looking into things... here: angular.io http
it seems you aren't supposed to stringify (anymore), so try:
postStockTake(stockTakeModel: string) : Observable<Response> {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(this.API_URL + "StockTake/AddToStockTake", { stockTakeModel }, options)
.map((res: Response) => res.json())
.catch((error: any) => Observable.throw(error.json().error || 'server error'));
}
You should authorise the header "Authorization" on your server side
I have also faced this issue and resolved it by removing proxy. Please check if you have set any proxy.
How to upload image using multipart on DreamFactory?
I am using angualr2, tried xhr and http.post. Both are not working I get 201 status code and with empty resource back. Document just says
POST http://{url}/api/v2/{storage_service_name}
Request header:
...
Content-Type: multipart/form-data;
...
Request payload:
-- <file content> --
no clear explanation
Been trying to figure this out too and the documentation really wasn't much help. This is what I eventually used
Created a component as below. The path input represents the folder already created on the files service. The code still needs to be refactored to create the folder if it doesn't exist, but this works so far.
import { Component, ElementRef, Input, ViewChild } from '#angular/core';
import { Headers, Http } from '#angular/http';
import * as constants from '../shared/config';
#Component({
selector: 'file-upload',
template: '<input type="file" #fileInput>'
})
export class FileUploadComponent {
#Input() multiple: boolean = false;
#Input() path: string = '';
#ViewChild('fileInput') inputEl: ElementRef;
baseResourceUrl: string = constants.API_BASE_URL + '/api/v2/files/';
constructor(private http: Http) {}
upload() {
console.log("changed");
let inputEl: HTMLInputElement = this.inputEl.nativeElement;
let fileCount: number = inputEl.files.length;
let fileName: string = '';
console.log(inputEl.files);
let formData = new FormData();
if (fileCount > 0) { // a file was selected
formData.append('files[]', inputEl.files.item(0), inputEl.files.item(0).name);
formData.append('pmCase', '100');
fileName = inputEl.files.item(0).name;
let myHeader = new Headers();
let token = localStorage.getItem('session_token');
myHeader.append('Content-Type', 'multipart/form-data');
myHeader.append('X-Dreamfactory-API-Key', 'xxxxxxxxxxx');
myHeader.append('X-Dreamfactory-Session-Token', token);
this.http
.post(`${this.baseResourceUrl + this.path + fileName}`, formData, { headers: myHeader })
.map((resp) => resp.json())
.subscribe((uploadResp) => {
console.log(uploadResp);
}, (error) => console.error(error));
}
}
}
You should check that the html input name for the file is "files" - Any other name for the file field will not upload content. Also, you need to post it to the directory or path that you want the file stored. Assuming the directory is already there, it should upload the file as expected. Good Luck!
I'm using Grails version 2.4.3 . I am creating an application that supports RESTful APIs. Since access to these APIs should be authenticated , I tried out the Spring Security REST plugin. I checked out this example and what I could understand is , the /api/login controller is the authentication point which receives the user credentials in JSON format and after successful authentication it provides the acces token as response. I tried sending a POST request to /api/login/ with valid JSON data using the POSTMAN Rest Client. But it gives me the following error.
401 Unauthorized , Similar to 403 Forbidden, but specifically for use when authentication is possible but has failed or not yet been provided. The response must include a WWW-Authenticate header field containing a challenge applicable to the requested resource.
I also tried using IntellijIDEA's REST Client but doesn't work.
Then i tried by sending AJAX Request to /api/login/ with valid JSON data
, but getting 401 on console. What is the problem here? Is this the correct login end point? How can i get authenticated using JQuery?
Try this
$.ajax({
url: " http://localhost:8080/AppName/api/login",
type: "POST",
crossDomain: true,
data: JSON.stringify({"username":"yourusername" , "password":"yourpassword"}),
contentType: 'application/json; charset=utf-8',
dataType: "json",
success: function (response) {
console.log(response);
},
error: function (xhr, status) {
alert("error");
}
}) });
You can try this code for authentication,I am sending user id and password in request header you can try as you wish :-
inject following services:-
def springSecurityService
def authenticationManager
and use following code
def login = {
final String authorization = request.getHeader("Authorization");
if (authorization != null && authorization.startsWith("Basic")) {
boolean authResult = authenticateUser(authorization)
if (authResult) {
render response.status
} else {
render authFailed(response)
}
} else {
render authFailed(response)
}
}
protected boolean authenticateUser(String authorization) {
// Authorization: Basic base64credentials
def base64Credentials = authorization.substring("Basic".length()).trim();
byte[] credentials = base64Credentials.decodeBase64()
String actualCredential = new String(credentials)
// credentials format like username:password
final String[] values = actualCredential.split(":", 2);
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(values[0], values[1]);
try {
def authentication = authenticationManager.authenticate(authRequest);
def securityContext = SecurityContextHolder.getContext();
securityContext.setAuthentication(authentication);
def session = request.session;
session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);
}
catch (BadCredentialsException exception) {
return false
}
return true
}
protected HttpServletResponse authFailedResponse(HttpServletResponse response) {
response.setStatus(401)
response.setHeader("WWW-Authenticate", "Basic realm=\"nmrs_m7VKmomQ2YM3:\"")
return response;
}