Rendr add custom header to fetch request (such as basic auth) - rendr

I'm building a Rendr app and I'd like to populate my user model by making a request to my API service's /login endpoint. That endpoint simply expects a basic auth header.
I see Rendr has an option to allow custom headers but the problem is the header is only added from the client to the Rendr node.js server. When the API proxy intercepts my requests and makes a call to http://my-api.com/login the basic auth header is not carried through to this request. I'm assuming the apiProxy ignores these headers- it has no way to know what header is custom.
How can I define a custom header client side and ensure the header is added to an API request?
this.app.fetcher.fetch({
user: {
model: 'User',
params: {}
}}, {
headers': {
"Authorization": "Basic abcdefg12345678"
}
}, function(err, user){
});
This example only adds a header from client -> Rendr node server, not NOT from Rendr node server --> my API service.

I put together an npm module for this: https://www.npmjs.com/package/rendr-api-proxy-optionable that should do what you need.
It allows pass throughs of request and response headers at the api proxy level.
Hope that helps!

Related

Putting a react-django staging site behind basic auth, but auth clashes with token auth for endpoints

Whats the situation?
I've got staging site which is built with Django + React.
Parts of the API you have to login to access. I'm using Django's token authentication for that.
I then wanted to put the entire site behind basic auth, to prevent anyone of accidentally stumbling across it.
What's the problem?
This means I need to pass two authentication methods with my requests. This is possible as described here.
Authorization: Token lksdjf893kj2nlk2n3rl2dOPOnm, Basic YXNkZnNhZGZzYWRmOlZLdDVOMVhk
The token is set in my JS code after being provided to the user when they login in.
Basic authentication is triggered on the first page load, after this the browser stores it and I believe automatically appends it onto any requests where the server has the following header:
WWW-Authenticate: basic
I have configured Django to return the following header:
WWW-Authenticate: basic, token
This successfully causes a XHR request sent via axios to have the basic header appended, when the Authorization header is empty.
The problem is the Authorization header isn't empty, because I need to set a token value in there.
const axiosConfig = {
method: requestType,
url: `${url}`,
withCredentials: true,
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
data: payload
};
// If we're logged in then send our auth token
if (localStorage.auth_token) {
// Axios can't see the basic authentication header here so we can't append.
console.log(axiosConfig.headers.Authorization);
// Basic auth will only get sent if I don't set anything here
axiosConfig.headers.Authorization = `Token ${localStorage.auth_token}`;
}
At this point the browser doesn't seem to append the basic header anymore and so my authentication fails.
Is there a way around this?
I wanted a blanket basic auth because there's no way I can accidentally expose anything on staging, otherwise I have to rely entirely on the token authentication and robots.txt which is less than ideal.
The answer in the end was port forwarding.
I removed basic auth, turned off ports 80 and 443 and then used port forwarding to map my SSH to local host.
i.e. ssh -N -L 8755:127.0.0.1:443 user#ip_address

how to skip Preflight Requset in vue with content-type:application/json

error :"405 not allowed Method" in post method type call in request command vue
i need call api function with content-type:application/json and post Method type with request command in vue ,but browser add preflight request with options method type and it causes this error :"405 not allowed Method"
var options = {
method: "POST",
url: "http://api.sample.com/login",
headers: {
"Access-Control-Request-Method":"POST",
"cache-control": "no-cache",
"content-type": "application/json",
},
body: '{ Username: "demo", Password: "demo", Domain: "test" }'
};
request(options, function(error, response, body) {
if (error) throw new Error(error);
body.data;
alert("ok");
});
The OPTIONS call is done whenever you do a cross-origin request. This means the domain your application is running on is different from the domain where the api is. A pre-flight request is mandatory for these requests, because the browser needs to figure out if you are allowed to do these requests. A 405 error means that the server thinks you are not allowed to make that request.
To solve this problem you can move your api to the same domain as your frontend. Please note that it cannot be on a subdomain.
A different way of solving this, is by sending back the correct headers. In your case you seem to at least miss the Access-Control-Allow-Methods response header. Make sure to send this header and either dynamically figure out which methods are allowed, or do something like the following. That would allow the most common methods to work.
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
In the comments you said that you do not have control over the api, and as such cannot change the response header. In that case your best bet is to contact whoever maintains the api and ask how to best use their api.
In the comments you said that this worked fine when you did the same thing in ASP.NET. ASP.NET is a server-side language, which means that requests in that context do not have a concept of "cross-origin". Cross-origin only comes into play in the browser, where the application runs on an actual domain.
Assuming you can set up a proxy on your application domain, you can also create a proxy that proxies all requests to the api you actually want to communicate with. You would deploy your domain on https://example.com and do your requests to https://example.com/api/endpoint. Your proxy will listen for requests that begin with https://example.com/api and proxy it to https://whatever.the.api.is/ with the appropriate endpoint and data.
Please keep in mind that while some api's might just be configured incorrectly, a lack of cross-origin response headers might just mean that the api is nog meant to be consumed through the browser. Part of this could be that the request contains a secret that should not be exposed to users that use your application, but should instead only be on the server. Using a proxy in that case would set you up for impersonation attacks, because you would expose the secret to your application, but defeat the cross-origin headers by making it appear to the application that the api is on the same domain.

Moqui REST API call fail with error code 403

From my Angular 2 application I am trying to get data from Moqui but the request always fails with the error code 403.
Here is the REST API call implementation
getExample() {
let url = 'http://localhost:8080/rest/s1/example/examples'
let headers = new Headers({ 'Authorization': 'Basic
am9obi5kb2U6bW9xdWk='});
headers.append('Accept', 'application/json, text/plain, */*');
headers.append('Content-Type', 'application/json; charset=UTF-8');
let options = new RequestOptions({ headers: headers });
let response = this.http.get(url, options).map(res => res.json());
return response;
}
The Moqui logs :-
REST Access Forbidden (no authz): User null is not authorized for View on REST Path /example/examples
There is also a similar question Moqui Rest Nginx but from the answer I do not know that where I have to change the settings in Moqui.
On the client console the error is :-
XMLHttpRequest cannot load http://localhost:8080/rest/s1/example/examples. Response for preflight has invalid HTTP status code 403
But with a rest client like YARC it works :-
You must authenticate for REST API calls except for Service REST API paths that are configured to not require authentication (like the /mantle/my end points in the mantle.rest.xml file in the mantle-usl component).
You have authentication but then there is one other step: authorization. In general if authc is required then authorization is also required. This is done with database records usually either in seed data and can also be added using the System app that is included in the default Moqui runtime (ie the moqui/moqui-runtime repository).
There is an example of authorization setup for Service REST API calls in the MantleSetupData.xml file. The main difference from screen authorization is that the artifact type to use is 'AT_REST_PATH'. Here is that file on GitHub (right near the top of the file):
https://github.com/moqui/mantle-usl/blob/master/data/MantleSetupData.xml
The best documentation for most things to do with REST requests in Moqui, is currently in the comments in the 'rest.xml' file that actually processes the incoming requests (ie handles the /rest path). You can see this on GitHub here:
https://github.com/moqui/moqui-runtime/blob/master/base-component/webroot/screen/webroot/rest.xml

ionic yii2 Response for preflight has invalid HTTP status code 500

I have a Ionic App and I'm trying to do a POST:
$http({
url: url+'/usuario/log',
method: 'POST',
data: {usuario : $scope.data.usuario, senha:$scope.data.senha},
headers : {'content-type':'application/json; charset=UTF-8'}
}).then(function(result) { ... });
On the server side I have a Yii2 application:
public function actionLog(){
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: *");
header("Access-Control-Allow-Headers: content-type");
$params = json_decode(file_get_contents('php://input'),true);
$usuario = $params['usuario'];
$senha = $params['senha'];
...
}
But the error I got is always this, I send a POST and get a OPTIONS
OPTIONS http://www.nexusolucoes.com.br/personal/web/usuario/log
XMLHttpRequest cannot load http://www.nexusolucoes.com.br/personal/web/usuario/log. Response for preflight has invalid HTTP status code 500
The problem seems to be related with CORS, if the backend is on a different domain than the frontend the browser will always send an OPTIONS request first, to confirm that the cross domain sharing is allowed for the frontend domain.
If the browser gets a proper response for the OPTIONS, then, the POST request (the one you want) will be triggered as usual.
To sum up, you need to: Add a mapping on the URL Manager to respond to the OPTIONS verb for the exact same URL where you're sending the POST. Then, you need to create an action within a controller or to use the Yii's yii\rest\OptionsAction along with the CORS filters to allow the frontend domain to make the POST request.
Please check the following links for more information:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
http://www.yiiframework.com/doc-2.0/yii-filters-cors.html
http://www.yiiframework.com/doc-2.0/guide-rest-controllers.html

how do you request a session from servicestack basic authentication, at /auth/basic?

I have set up a servicestack service with basic authentication using the first example, here:
https://github.com/ServiceStack/ServiceStack/wiki/Authentication-and-authorization
This automatically sets up a route: /auth/basic
However, I cannot find any information or examples on how to format a request to this URL (Variables/GET/POST/Auth Header, etc.).
I am able to access a simple service using the basic authentication credentials, so they are active and correct.
I have no custom authentication plugged in, just basic authentication.
I have tried:
Using a JsonServiceClient to send UserName and Password variables by GET or Json POST to /auth/basic, with and without an Auth header also containing the user & pass.
Using a browser to send GET requests with URL parameters of the user/pass, or as http://user:pass#localhost:123/auth/basic
I always just get "HTTP/1.1 401 Invalid BasicAuth credentials".
The only examples I can find involve some kind of custom authentication, and then /auth/credentials is accessed, but I want to use /auth/basic
I have looked at the code and it looks like it reads an Auth header, but the service does not accept one.
I am actually trying to get this working so I can then disable it and verify it is disabled (I want to require basic authentication for every request).
Questions are:
What is the correct way to call the /auth/basic service? I will take a servicestack client API example, specifications or even a raw http request!
How do you disable the /auth services altogether?
Many thanks.
What is the correct way to call the /auth/basic service? I will take a servicestack client API example, specifications or even a raw http request!
var client = new JsonServiceClient("http://localhost:56006/api");
var resp = client.Post(new Auth() { UserName = "TestUser", Password = "Password" });
This assumes you have also registered an ICacheClient and IAuthUserRepository (and added a user account)
The JSON format looks like this if you call into /auth/basic?format=json
{
"UserName": "admin",
"Password": "test"
"RememberMe": true
}
How do you disable the /auth services altogether?
Don't add the AuthFeature plugin to configuration.
You can also remove plugins
Plugins.RemoveAll(x => x is AuthFeature);
Putting the following in apphost config seems to do the trick.
//Disable most things, including SOAP support, /auth and /metadata routes
SetConfig(new EndpointHostConfig()
{
EnableFeatures = Feature.Json | Feature.Xml
});
I am a little suspicious about what this does to /auth however, because it returns an empty response, while most routes return 404.
So, would this truly disable the /auth functionality? As in, if someone formed a correct request to /auth/credentials, will it still return an empty response?