What is the parameter name for basic authentication in meteor's http.post API? - meteor

I'm using HTTP.post in meteor and I need to send basic authentication with only a username to an external service. Where does this go and what would that look like?
I am only using it on the server side so I know it should look like the below code, but I'm not sure where to put the username and what to call it.
I've tried this.
var resultSet = HTTP.post("https://billy.balancedpayments.com/v1/customers", {
params: {"processor_uri": "/customers/customerURI"},
authentication: {"MYKEYHERE":""}
});
And this.
var resultSet = HTTP.post("https://billy.balancedpayments.com/v1/customers", {
params: {"authentication": "MYKEYHERE",
"processor_uri": "/customers/customerURI"}
});
And this.
var resultSet = HTTP.post("https://billy.balancedpayments.com/v1/customers", {
params: {"processor_uri": "/customers/customerURI"
},
headers: {'Authorization': 'MYKEYHERE'}
});
I get this error each time.
Error: failed [403] 403 Forbidden Access was denied to this resource.
Unauthorized: CustomerIndexView failed permission check

The plain auth : 'username:password' should do (from docs):
var resultSet = HTTP.post("https://billy.balancedpayments.com/v1/customers", {
params: {"processor_uri": "/customers/customerURI"},
auth: 'yourkey:'
});
As per the balanced payments documentation:
To authenticate with Balanced, you will need the API key secret provided from the dashboard. You have to use http basic access authentication. Your key has to be set as the username. A password is not required for simplicity.
So this means you leave the password blank, so its just your key followed by the colon :
Also you might want to consider using the balanced package for Meteor which does all the boilerplate for you.

Related

Creating new document with Firestore REST API and Local Emulator Suite, Returning Error 404: Problem with Path Parameter

I’m just getting acquainted with Firebase/Firestore as a beginner coder, and I'm attempting to create an integration test for a set of callable functions a friend had written for their project. I am writing a test to automate testing using the Firebase local emulator suite.
Right now, I'm attempting to write a POSt request using Axios that will create a document in a given collection in my local emulator suite, after having received an Id Token from generating an authorized user.
The project id is called okane-crud-dev. I’ve created a collection
called test.
I have created an authenticated user with a given email and password, and generated the unique Id Token from an initial post request:
interface createPostRequest {
url: string;
data: Object;
config: Object;
};
//create an instance of a user
const createUserInstance : createPostRequest = {
url: 'http://localhost:9099/identitytoolkit.googleapis.com/v1/accounts:signUp?key=hi',
data: {
'email': 'myemail#email.com',
'password': 'mypassword',
'returnSecureToken': true
},
config: {
'headers':
{'Content-Type': 'application/json'}
},
};
const createUserResponse = await axios.post(createUserInstance.url, createUserInstance.data, createUserInstance.config);
const userIdToken = createUserResponse.data.idToken;
const userLocalId = createUserResponse.data.localId;
Up to this point, I have had no issues.
As for the second POST request to create a document, this is my code. I used this post as a reference:
Creating new collection and document with Firestore REST API returning HTTP 400
const createDocumentInstance : createPostRequest = {
url: "https://firestore.googleapis.com/v1beta1/projects/'localhost:8080/okane-crud-dev'/databases/(default)/documents/test",
data: {
"fields": {
"localId": userLocalId,
'budget': '2000',
}
},
//directly pasted IdToken as using the variable resulted in problem with ' ' error
config: {
'headers':
{
'Content-Type': 'application/json',
'Authorization': `Bearer ${userIdToken}`,
}
}};
console.log(createDocumentInstance);
const createDocument = await axios.post(createDocumentInstance.url, createDocumentInstance.data, createDocumentInstance.config);
const docReference = createDocument.data;
console.log(docReference);
When I attempted to run this, the following error was returned:
Request failed with status code 404
at createError (../../node_modules/axios/lib/core/createError.js:16:15)
at settle (../../node_modules/axios/lib/core/settle.js:17:12)
at IncomingMessage.handleStreamEnd (../../node_modules/axios/lib/adapters/http.js:293:11)
I'm a beginner and am just starting to learn how to code, so bear with me if this is an easy answer as I'm still figuring out how to debug.
I know that a 404 error means an issue with locating the resource -> and after making some adjustments to the headers, I figured the issue must be in my URL. I’ve tried looking around for other posts that use local emulator suite and POST requests to figure out if there was something wrong with how I wrote the path.
"https://firestore.googleapis.com/v1beta1/projects/'localhost:8080/okane-crud-dev'/databases/(default)/documents/test"
I've been looking at the Firebase documentation closely for creating a document; https://firebase.google.com/docs/firestore/reference/rest/v1beta1/projects.databases.documents/createDocument#path-parameters
Borrowing from the other post, I’ve tried different variations of where to include the emulator suite port: localhost:8080 and the project id “okane-crud-dev”. But haven’t seemed to figure out. I made sure that the project id was connected to my local emulator suite. Does anyone have any suggestions?
If you're using the Firestore Emulator with the REST API, you should change the base URL https://firestore.googleapis.com/v1 to your localhost http://localhost:8080/v1 then proceed with the path of your Firestore database.
http://localhost:8080/v1/projects/okrane-crud-dev/databases/(default)/documents/test

Firebase Realtime Database returns 401 when trying to authenticate?

I am using REST API in my app to communicate with a Firebase RTDB, and trying to use a Google Access Token to authenticate my requests.
My issue is that with even the most permissive Rules on the database, I get HTTP error 401 in response to queries that try to authenticate.
For example, say I try to put some data in my database with the following command, I get 401 in return (all the values within < > are placeholders):
curl -XPUT -d '{ "UserID" : "<GOOGLE_UID>", "UserName" : "Clicksurfer", "CompletionMoves" : 8, "CompletionTime" : 16.21979 }' https://<FIREBASE_URL>.firebaseio.com/Level2/<GOOGLE_UID>.json/?access_token=<GOOGLE_ACCESS_TOKEN>
401
The strangest part is, when I abandon the use of access token altogether the query works:
curl -XPUT -d '{ "UserID" : "<GOOGLE_UID>", "UserName" : "Clicksurfer", "CompletionMoves" : 8, "CompletionTime" : 16.21979 }' https://<FIREBASE_URL>.firebaseio.com/Level2/<GOOGLE_UID>.json
200
As I said, I am currently using the most permissive rules for debugging:
{
"rules": {
".read": true,
".write": true
}
}
Any idea what might be causing this? Thanks in advance
EDIT:
I use the Google Play Games plugin for Unity in my project, among other things to get the AuthCode.
In order to do this, I needed to do a couple of things:
When building the config for Google Play Games during startup, I made sure to call the RequestServerAuthCode(false) method
Have the user login after Google Play Games sets up
Make sure that the relevant ClientID was supplied to Unity (in this case, it is a web client that has auth permissions on my Firebase rtdb).
This all looks like this:
public class GPGSAuthentication : MonoBehaviour
{
public static PlayGamesPlatform platform;
void Start()
{
if (platform == null)
{
PlayGamesClientConfiguration config = new PlayGamesClientConfiguration.Builder().RequestServerAuthCode(false).Build();
PlayGamesPlatform.InitializeInstance(config);
PlayGamesPlatform.DebugLogEnabled = true;
platform = PlayGamesPlatform.Activate();
}
Social.Active.localUser.Authenticate(success =>
{
if (success)
{
Debug.Log("GSPS - Logged in successfully");
}
else
{
Debug.Log("GSPS - Falied to login");
}
});
}
}
Now that we've done this, we can call PlayGamesPlatform.Instance.GetServerAuthCode() in order to get the AuthCode.
I traded in my AuthCode for an Access Token by sending a POST request to https://www.googleapis.com/oauth2/v4/token. In my query, I supply 4 fields:
client_id, which has the ID of the previously used client (where we got the AuthCode from).
client_secret, which has the correlating secret.
grant_type, which is always with the value "authorization_code"
code, which has the value of the AuthCode we got.
In response, I get a 200 response with 4 parameters:
access_token, the token I (fail to) use when authenticating against my Firebase rtdb.
token_type, the type of the aforementioned token.
expires_in, the amount of time before the token expires (I presume in seconds unit)
refresh_token, a token which can be used in order to get a new access_token without having to keep the Google user connected.
I then supply this access_token value to the queries I send to my DB, and promptly get the 401 error.

Firebase service account to generate authentication token for client-side use with Google Apps Script

I am having difficulty using the FirebaseApp (a 3rd party API) to generate an authentication token that can be passed to a sidebar and used by the client to login and access my Firebase Database client-side.
I'm trying to use this tutorial but cannot get it working without using a database secret (which is being depreciated) in makeToken(). I'd prefer to use a service account as reflected in this tutorial. When I look at the difference between the tokens generated, the first 2 pieces separated by a '.' are identical, the last piece after the final '.' is different. The lengths are the same as well. eg:
//Example Generated by Database Secret: TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBv.ZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=.dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2U=
//Example Generated by Service Account: TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBv.ZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=.IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbml=
I can generate the OAuth access token, pass it to FirebaseApp and generate an authentication token, but when it is passed client-side and I attempt to authenticate I get an error: Login Failed! Error: INVALID_TOKEN: Failed to validate MAC.
It seems like there is a lot of misinformation and conflicting information on how this should be done.
I have a getFirebaseService() function server-side that uses Apps Script OAuth2 Library to get an access token.
function getFirebaseService() {
return OAuth2.createService('Firebase')
// Set the endpoint URL.
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
// Set the private key and issuer.
.setPrivateKey(fb_PRIVATE_KEY) //Service account private key
.setIssuer(fb_SERVICE_EMAIL) //Service account email
// Set the property store where authorized tokens should be persisted.
.setPropertyStore(PropertiesService.getScriptProperties())
// Set the scopes.
.setScope('https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/firebase.database');
}
I have a makeToken() function server-side that gets an authentication token from Firebase using the OAuth access token. I am able to use the service.getAccessToken() OAuth token server-side to access and store data. So that works, I guess my issue is creating a client auth token that's more restrictive.
function makeToken(){
var service = getFirebaseService();
if (service.hasAccess()) {
return FirebaseApp.getDatabaseByUrl(fb_URL, service.getAccessToken()) //Database Secret Works: "AAslhfi3MYACCESSTOKEN2930hf03ah4th8" but is being depreciated.
.createAuthToken(Session.getActiveUser().getEmail());
} else {
Logger.log("makeToken: " + service.getLastError());
}
}
Then client-side, from the sidebar, I try to authenticate with a custom auth token retrieved server-side from makeToken().
var userAuthToken;
google.script.run.withSuccessHandler(function (requestAuthToken) {
userAuthToken = authenticateClient(requestAuthToken)
}).makeToken();
function authenticateClient(userRequestToken) {
var ref = new Firebase(fb_URL);
ref.authWithCustomToken(userRequestToken, function (error, authData) {
if (error) {
console.log("FB Login Failed!", error); //Error below come from here.
}
else {
console.log("FB Login Succeeded!", authData);
}
});
return ref.authData.auth;
}
This results in Login Failed! Error: INVALID_TOKEN: Failed to validate MAC..
Edit: Is it possible FirebaseApp is incorrectly generating the JWT Authentication Token?
Edit2: I think the above edit is unlikely as I attempted to use the GSApp library and had the same issue. It only seems to want the depreciated database secret, not a service account OAuth.
Alright, so after a very long day I figured it out. I'm going to lay out what I ended up using for libraries and what the issue was (see the third library). The main problem was essentially that the tutorial was outdated and no a lot of people use Firebase in apps script.
OAuth2 (Server-side)
Link
I didn't have to change anything here! It was working fine and never an issue.
FirebaseApp (Server-side)
Link
This is a nice library and I stuck with it because it worked well (once I got it there). I had to make a change to my original code that came from the tutorial I mentioned. My code ended up like this and worked:
if (service.hasAccess()) {
return FirebaseApp.getDatabaseByUrl(fb_URL, service.getAccessToken()) //get OAuth Token
.createAuthToken(Session.getEffectiveUser().getEmail(), null, serviceAccount.client_email, serviceAccount.private_key);
//... Added the null, private key, and service email parameters.
Firebase (Client-side)
Link
Alright, so this is where my main issue was -- The tutorial I followed for client-side setup was old. I had to upgrade the code on my own to use the new 3.x version:
<script src="https://www.gstatic.com/firebasejs/5.8.2/firebase.js"></script>
// Initialize Firebase
var config = {
apiKey: "<Web API Key>",
authDomain: "<Project ID>.firebaseapp.com",
databaseURL: "https://<DB URL>.firebaseio.com/"
};
firebase.initializeApp(config);
With this firebase instance I was able to update my original authenticateClient() method:
function authenticateClient(userRequestToken) {
firebase.auth().signInWithCustomToken(userRequestToken).catch(function(error) {
// Handle Errors here.
console.error("authClient: ", error.code, error.message);
});
return {
uid: firebase.auth().currentUser.uid,
metadata: {
lastSignInTime: firebase.auth().currentUser.lastSignInTime
}
};
}
That's it! I now have a firebase instance with a signed in user via JWT Custom Token! I came across a few people with similar issues an I hope this helps.

Issue with jwt-bearer on-behalf-of grant in Azure AD

So I have an Angular app that uses the adal-angular library to authenticate with an ASP.NET Core 2.0 Web API. The API then uses on-behalf-of flow to authenticate with another API using the users token like this MS article https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-on-behalf-of.
The issue I have is this is working fine in the DEV environment but I have now deployed a TST environment with separate App Registrations and I am receiving the following exception when I try and request the token using on-behalf-of
AADSTS240002: Input id_token cannot be used as 'urn:ietf:params:oauth:grant-type:jwt-bearer' grant.
The code I am using to request the token
public async Task<string> AcquireTokenAsync(string resource)
{
try
{
string accessToken = await _httpContextAccessor.HttpContext.GetTokenAsync(AuthenticationConstants.AccessToken);
var credentials = new ClientCredential(_azureOptions.ClientId, _azureOptions.ClientSecret);
var authContext = new AuthenticationContext($"{_azureOptions.Instance}{_azureOptions.TenantId}")
{
ExtendedLifeTimeEnabled = true
};
// On-behalf-of auth token request call
var authResult = await authContext.AcquireTokenAsync(
resource,
credentials,
new UserAssertion(accessToken));
return authResult.AccessToken;
}
catch (AdalServiceException asex)
{
_logger.LogError(asex, $"Instance: {_azureOptions.Instance} Tenant: {_azureOptions.TenantId} ClientId: {_azureOptions.ClientId}");
throw;
}
catch (System.Exception ex)
{
_logger.LogError(ex, ex.Message);
throw;
}
}
And I have used Fiddler and it looks like all the correct parameters are being passed.
Any help would be very much appreciated. I have set knownClientApplications on the second API and I have granted permissions on the Angular backend API to the second API.
For me, I got it to work by changing BOTH of the following to true:
oauth2AllowImplicitFlow
oauth2AllowIdTokenImplicitFlow
See here for more information.
According to your question and the error, it should be caused by that you angular app is not a Native(public) app.
For using this OBO flow with this Grant type, your client must be a public client not credential client.
If you want to register your client as a WebApp/API, you can refer to this Implementation:
Hope this helps!
Update
According to OP's comment, he/she got it working by changing oauth2AllowImplicitFlow from false to true.
We had this problem last week with one Azure Service Registration and not another. A review found that the token didn't return an AIO being returned. It turns out that the registration had redirects with wildcards (e.g., https://*.ngrok.io) and this is incompatible with the AcquireTokenOnBehalfOf function. I'm posting this here so a future person, probably me, will find it.
I was having problems even when oauth2AllowImplicitFlow and oauth2AllowIdTokenImplicitFlow were set to true. One of my Reply URLs had a wildcard in it. When the wildcard was removed, the issue was resolved.

Meteor 1.0 - Custom Authentication Rules

I've a meteor app which uses Neo4j as a database with neo4jreactivity driver. Since I'm not using Mongo, Meteor.loginWithPassword(email, password, function(err) {...}) doesn't work. My question is:
How do I define custom authentication rule to login to the app?
kind of like:
customLogin(email, password, function() {...});
You can use the Accounts.registerLoginHandler method to accomplish this. This function allows developers to add custom authentication methods. Check out https://meteorhacks.com/extending-meteor-accounts.html for a great article with more details.
You likely want to continue to use loginWithPassword, and register a loginHandler similar to the one in Meteor's accounts-password package (see
Meteor's implementation ), with the call to Meteor.users.findOne(selector) replaced with a database lookup in Neo4j.
If you want to use a custom login method, your code might look something like the code from here (modified for the purposes of this question). Note that this code is not complete, nor is it a secure means of authenticating:
// client-side
// This function can be called to log in your users, and will
// trigger the following
Meteor.loginWithNeo4j = function(email, password, callback) {
//create a login request with the email and password passed in
var loginRequest = {email: email, password: password};
//send the login request
Accounts.callLoginMethod({
methodArguments: [loginRequest],
userCallback: callback
});
};
// server-side
Accounts.registerLoginHandler(function(loginRequest) {
// loginRequest is a JS object that will have properties
// "email" and "password as passed in the client code
// -- here you can write code to fetch the user's ID from the database
// take a look at https://github.com/meteor/meteor/blob/devel/packages/accounts-password/password_server.js#L61
// to see how meteor handles password checking
return {
userId: userId
}
});
The accounts package in general has a lot of dependencies on MongoDB, but you should be able to piece together various methods from the package to get auth to work.
To fetch user's object use:
Meteor.neo4j.query('MATCH (a:Player {_id: "kE3ypH4Um"}) RETURN a').get().a[0]
/* or by email */
Meteor.neo4j.query('MATCH (a:Player {email: "name#domain.com"}) RETURN a').get().a[0]
Also see updated driver API

Resources