Authentication proxy - req.user.sub persistent? - node.js

Situation
I used the node.js quickstart project from auth0 to build an authentication-proxy. Reason for this is that I cannot merge my spring backend with the Quickstart spring example.
In order to let the spring backend identify the user, I pass the user's sub as shown below.
var authenticate = jwt({
secret: new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64'),
audience: process.env.AUTH0_CLIENT_ID
});
...
app.get('/secured/*', function (req, res) {
var url = apiUrl + req.url;
var userId = req.user.sub; // 'auth0|muchoCrypto123'
url += "?userId=" + userId;
req.pipe(request(url)).pipe(res);
});
I am currently also investigating the usage of HttpRequestServlet in spring to retrieve user details.
Question
Is req.user.sub a value that I can use to identify the user without worrying that this value might change? So far I couldn't detect changes.

In the user management console I found the following:
user_id auth0|muchoCrypto123
Thus I assume that the user_id won't change. Can anyone confirm?

Related

Generate Authorization token for MuleSoft API in NetSuite

I am trying to call Mulesoft API endpoint from NetSuite user event script. I need to generate token to send it with API call.
Question:
should i create schedule script to generate the token and store it somewhere?
how often the token should be refreshed?
Postman token generation is working fine. I would love to know how should I setup this in NetSuite.
Postman:
Apologies in advance as I cannot comment, low Rep.
I haven't worked with Mulesoft or Oauth2, I mostly work on Oauth1.
According to your comments, it expires in 4 Hours. I suggest you store the generated Access Token in Script Parameter. NetSuite Script Parameter. You can call task.create to schedule a script to refresh the Access Token every 4 hours as stated on the notes on this page Referencing Script Parameters
EDIT: Had to confirm few things regarding Script Parameter. According to some articles, Script Parameter are global and can be called from different scripts (has to be set as company preference when creating parameter). So, scheduled script and storing it to a parameter and having your UE Script fetching the value of that parameter will work.
Adding this code sample to #Nukedd's answer.
Here's an example of storing/fetching access token in Cache.
const CACHE_NAME = 'MY_CACHE';
const ACCESS_TOKEN = 'MY_ACCESS_TOKEN';
const cache = require('N/cache');
// Storing access token to server cache
const storeAccesstoken = () => {
var myCache = cache.getCache({
name: CACHE_NAME,
scope: cache.Scope.PRIVATE
});
myCache.put({
key: ACCESS_TOKEN,
value: '12345accesstoken',
ttl: 14400
});
}
// Fetching access token from server cache
const getAccessToken = () => {
const myCache = cache.getCache({
name: CACHE_NAME
});
const myAccessToken = zipCache.get({
key: ACCESS_TOKEN,
loader: loaderFunction
});
return myAccessToken;
}
Please see the following:
N/cache Module
cache.Scope
Note: This is only supported by server scripts.

Azure keyvault, request for multiple secrets

Im making use of the following node library azure-keyvault to get retrieve stored secrets from azure keyvault. Ive only found the client.getSecret api exposed to retrieve a secret value. Im searching for a way to retrieve multiple secret values in one call. I hav'nt found one yet. Is there a way to do this that i'm missing or its simply not supported.
const { SecretClient } = require('#azure/keyvault-secrets')
const client = new SecretClient(
`https://${KEYVAULT_NAME}.vault.azure.net`,
new DefaultAzureCredential()
)
const [secret1, secret2] = await Promise.all([
client.getSecret(`secret1`),
client.getSecret(`secret2`)
])
Here is the complete code for getting the multiple client secret at once:
var credentials = new KeyVault.KeyVaultCredentials(authenticator);
var client = new KeyVault.KeyVaultClient(credentials);
client.setSecret(vaultUri, 'mysecret', 'my password', options, function (err, secretBundle) {
// List all secrets
var parsedId = KeyVault.parseSecretIdentifier(secretBundle.id);
client.getSecrets(parsedId.vault, parsedId.name, function (err, result) {
if (err) throw err;
var loop = function (nextLink) {
if (nextLink !== null && nextLink !== undefined) {
client.getSecretsNext(nextLink, function (err, res) {
console.log(res);
loop(res.nextLink);
});
}
};
console.log(result);
loop(result.nextLink);
});
});
You can find the complete reference for azure key vault using node js below:
http://azure.github.io/azure-sdk-for-node/azure-keyvault/latest/KeyVaultClient.html#getSecrets
http://azure.github.io/azure-sdk-for-node/azure-keyvault/latest/
Hope it helps.
You can use read-azure-secrets npm package which will return all secrets to you.
E.g.
const secretClient = require('read-azure-secrets');
async function loadKeyVaultValues() {
let applicationID = '';
let applicationSecret = '';
let vaultURL = 'https://<your-key-vault-name>.vault.azure.net/';
let secrets = await secretClient.getSecrets(applicationID, applicationSecret, vaultURL);
secrets.forEach(secret => {
console.log(secret);
});
}
loadKeyVaultValues();
You can try using client.getSecrets(..) method exposed by the REST Api.
Kindly go through the following useful blog, in which all methods have been implemented.
LINK: https://www.red-gate.com/simple-talk/cloud/platform-as-a-service/using-azure-keyvault-with-node-js/
You haven't specified what information about the secret you want to fetch so I am going to assume that you are looking for the secret's value. I am also going to assume you are looking to minimize network traffic for fetching multiple secrets (either for costs or for performance).
Looking at the Azure REST API documentation while there is a route to list multiple secrets it only provides the secret identifier and metadata about the secret (attributes, tags, etc). So if you want to get the secret's value (the actual secret) you will need to make individual calls although get-secrets route can be used to find all the secrets stored in the Key Vault.
As far as the client library, #azure/keyvault-secrets maps pretty closely to the REST API it supports so it will not provide a method that fetches multiple secrets. Even if it did, it would just be a facade over multiple network calls so it would not help reduce the number of network trips.
So to answer your question - it does not look possible today unless all you want is metadata about the secret and not the secret value itself.

DocuSign Node SDK not returning loginInfo in Production

I've built out an integration using DocuSign's Node SDK. While testing using a DocuSign sandbox account, the authentication flow works just fine using the example in the docs.
I'm now trying to do the same within a live DocuSign production account using the Integrator Key that was promoted from the sandbox account. authApi.login() seems to work just fine, I get no error and the status code of the response is 200. However, the value of loginInfo comes back as exports {} with no account info included.
I've made sure to change the base path from https://demo.docusign.net/restapi to www.docusign.net/restapi and as far as I can tell from the docs, there doesn't seem to be anything else I need to make the switch to production. Here is the code I am using:
apiClient.setBasePath('www.docusign.net/restapi');
apiClient.addDefaultHeader('Authorization', 'Bearer ' + token);
docusign.Configuration.default.setDefaultApiClient(apiClient);
const authApi = new docusign.AuthenticationApi();
const loginOps = {
apiPassword: true,
includeAccountIdGuid: true
};
authApi.login(loginOps, function (err, loginInfo, response) {
if (err) {
console.log(err);
}
if (loginInfo) {
// loginInfo returns 'exports {}' so the variables below cannot be set.
const loginAccounts = loginInfo.loginAccounts;
const loginAccount = loginAccounts[0];
const baseUrl = loginAccount.baseUrl;
const accountDomain = baseUrl.split('/v2');
const accountId = loginAccount.accountId;
apiClient.setBasePath(accountDomain[0]);
docusign.Configuration.default.setDefaultApiClient(apiClient);
www.docusign.net endpoint will only work if your PROD account is in NA1, if your PROD Account is in NA2, then you need to use na2.docusign.net and if it is in NA3 then na3.docusign.net. This is the main reason you should use /oauth/userinfo call with OAUTH2 Access Token to know your base URL, and then call all APIs with this baseURL. You can find more details at https://docs.docusign.com/esign/guide/authentication/userinfo.html

USER_AUTHENTICATION_FAILED Creating Envelope

Currently I'm working with a Node.js integration for DocuSign (https://www.npmjs.com/package/docusign-esign), I made all the test with the sandbox account and worked perfectly, right now I'm trying to use a production account, the login process is fine but when I'm going to create the envelope I get a USER_AUTHENTICATION_FAILED error (even if the first login went without errors). I would like to know if someone has experienced same thing or has an idea of how can I fix this.
This is the code that I took from the docusign-esign to create the envelope:
var loginAccount = new docusign.LoginAccount();
loginAccount = loginAccounts[0];
var accountId = loginAccount.accountId;
var envelopesApi = new docusign.EnvelopesApi();
envelopesApi.createEnvelope(accountId, envDef, null, function (error, envelopeSummary, response)
The account Id is the same retrieved after the login process.
One possible cause could be that your DocuSign account is hosted on na2.docusign.net, na3.docusign.net or eu.docusign.net, while your code uses the default www.docusign.com as a base URL.
The login call will pass even if you use www, however all the subsequent API calls will fail if you are not hitting the exact base URL that corresponds to your production account. You should have received this information as part of the DocuSign Go-Live process (formerly known as API Certification). You can always get the base URL from the login call response.
For Node, here how to get the correct base URL from the login call and set it up to the API Client (lines in bold are likely what is missing in your code):
authApi.login(loginOps, function (err, loginInfo, response) {
if (err) {
return next(err);
}
if (loginInfo) {
// list of user account(s)
// note that a given user may be a member of multiple accounts
var loginAccounts = loginInfo.getLoginAccounts();
console.log('LoginInformation: ' + JSON.stringify(loginAccounts));
var loginAccount = loginAccounts[0];
var accountId = loginAccount.accountId;
var baseUrl = loginAccount.baseUrl;
var accountDomain = baseUrl.split("/v2");
apiClient.setBasePath(accountDomain[0]);
docusign.Configuration.default.setDefaultApiClient(apiClient);
next(null, loginAccount);
}
});

Express.js how to use security on login and afterwards

I have a web app being built in express.js with a postgresql db.
I was wondering about how to implement the security, but everyone uses something different ( i guess thats a good thing? ).
Different modules different authentication sequences etc.
What I have at the moment:
1) User form post to for example /login
2) app routes to specific route
3) in route I try the following
var localconstring = "postgres://" + usr + ":" + pass + "#ip:port/db";
var client = new pg.Client(localconstring);
client.on('drain', client.end.bind(client));
client.connect(function (err, client, done) {
The database uses md5 so the pass is already protected by the db.
What should really happen?
Should I salt and hash the username and password and then save the salted/hashed credentials alongside the salt and then use the md5 of the db also?
If so which module?
Should I be logging in like that or try to do a select * from pg_roles/users ??
Thanks a lot!
(regarding the salt and hash if possible some detailed examples as I am pretty knew with authentication security)
Forgot to mention. cookies..
After the authentication I set the following cookies:
res.cookie('user', req.body.lguser.username, { signed: true })
res.cookie('watcher', o, { signed: true })
And look em up afterwards
req.signedCookies.user !== undefined
Is the signed attribute secure?
You should generate a key. This key should be saved on a cookie and on the database. Then when the user makes a petition, you can get the key on the cookie and search the user on the database.
There are libraries that help you on this, take a look at Passportjs:
http://passportjs.org/
First of all md5 is NOT seure anymore, so I would recommend you using 'sha512'.
A snippet would be something like this:
var crypto = require('crypto');
var salt = crypto.pseudoRandomBytes(32);
crypto.pbkdf2(userPassword,salt,1024,32,function(err,finalPassword){
//on the db you save the salt as a field and the SALTEDPASSWORD !!
//in this case the finalPassword
}
So when the user logs-in you get the user from the db by username and do the following:
//after getting the user from DB recalculate the hash
crypto.pbkdf2(passw,user.salt,1024,32,function(err,corrPass){
if(corrPass.toString() == user.password.toString()) // log in the user
//where user.password is the result from the db query
}
And I do recommend using passport like the other dude said, it simplifies all of the cookie stuff.
Hope it helped !

Resources