AWS cognito nodejs - node.js

I am working in a project in which the authentication is managed by AWS cognito. I have implemented google authentication with cognito. I was successful to get google auth token and pass it to the backend. I created an identity pool in aws. Now, i want to return the aws session token back to the UI from backend. So far I managed to write the code,
function login(token){
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'myidpoolid',
Logins: {
"accounts.google.com": token,
},
});
AWS.config.credentials.get(function(){
// Credentials will be available when this function is called.
var accessKeyId = AWS.config.credentials.accessKeyId;
var secretAccessKey = AWS.config.credentials.secretAccessKey;
var sessionToken = AWS.config.credentials.sessionToken;
});
return AWS.config.credentials;
}
let credentials = login(google_token);
>>>>>Here credentials is empty
return JSON.stringify({'Message':"Sample message",'data':credentials})
But I am not able to return this credentials to where i call the login method. I get only an empty result. I am a newbie to nodejs.Please help

Related

NodeJS AWS DynamoDB V3 How to refresh assumed role permissions

we managed to assume a role, but it does not automatically refresh access, so after some time we get a timeout err.
We found not proper documentation on how to refresh credentials, so I was wondering if someone could provide a code example of how to setup this up properly.
We already tried with credentialDefaultProvider({ assumeRole }) in the DynamoDBClient constructor options, but it doesn't even call it.
AWS Secure Token Service is your friend for assuming a role and use its credentials.
// this example uses Typescript
import { AssumeRoleCommand, Credentials, STSClient } from '#aws-sdk/client-sts'
// get / refresh Credentials
const stsClient = new STSClient({ region: <YOUR_REGION> })
const data = await stsClient.send(
new AssumeRoleCommand({
RoleArn: <ROLE_ARN>,
RoleSessionName: <SOME_SESSION_NAME>,
DurationSeconds: <DURATION_IN_SECONDS>
}),
)
// now use the Credentials
// data.Credentials
You can also check if the Credentials are still valid before your requests:
if(new Date() > new Date(data.Expiration)){
// refresh Credentials
}
Useful links:
AWS Secure Token Service
AWS STS Example

Azure App Service Authentication / Authorization and Custom JWT Token

In my web project i want to enable the user to login with username / password and Microsoft Account.
Tech - Stack:
Asp.Net Core WebApi
Angular
Azure App Service
First i created the username / password login. Like this:
StartUp.cs:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(Configuration["JWTKey"].ToString())),
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = true
};
});
Login Method:
public async Task<IActionResult> ClassicAuth(AuthRequest authRequest)
{
tbl_Person person = await _standardRepository.Login(authRequest.Username, authRequest.Password);
if (person != null)
{
var claims = new[]
{
new Claim(ClaimTypes.GivenName, person.PER_T_Firstname),
};
var key = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(_config["JWTKey"].ToString()));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Expires = DateTime.Now.AddHours(24),
SigningCredentials = creds
};
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);
return Ok(tokenHandler.WriteToken(token));
}
else
return Unauthorized("Invalid login data");
}
And secured my api enpoints with [Authorize].So far so good...that works.
Now i want to add a login method with Microsoft Account. I use Azure App Service Authentication / Authorization for that (https://learn.microsoft.com/de-de/azure/app-service/overview-authentication-authorization).
I configured the auth provider and i'm able to start the auth flow with a custom link in my angular app:
Login with Microsoft - Account
This works and i can retrieve the access token from my angular app with this:
this.httpClient.get("https://mysite.azurewebsites.net/.auth/me").subscribe(res => {
console.log(res[0].access_token);
});
Now the problem:
access_token seems not a valid JWT Token. If i copy the token and go to https://jwt.io/ it is invalid.
When i pass the token to my API i get a 401 - Response. With seems logical because my API checks if the JWT Token is signed with my custom JWT Key and not the Key from Microsoft.
How can I make both login methods work together? I may have some basic understanding problems at the moment.
It seems you want your Angular app calling an ASP.NET Core Web API secured with Azure Active Directory, here is a sample works well for that.
The most important step is register the app in AAD.
By the way, if you want to enable users to login one project with multiple ways in azure, you can use multiple sign-in providers.

Keyvault Authentication using username and password

The customer has created a key vault and store the credentials . To authenticate key vault , I have created the application in the node and using client id and client secret , I am able to read the secrets. But now the customer wants not to use the client id and client secret , instead use the username and password of the AZURE to access the keyvault in the program. Its one dedicated user for the keyvault access with no MFA.
I am not sure if we can access the keyvault with username and password from the node js. Kindly suggest.
Thanks
For this requirement, I also think that use username-password flow is unnecessary and client credential flow should be better (as juunas mentioned in comments). But if the customer still want to use username-password flow to implement, I can provide a sample as below for your reference:
1. You should register an app in AD with native platform but not web platform.
And please check if "Treat application as a public client" is enabled.
If your app is web platform, when you run the node js code it will show error message to ask you provide "client secret" even if you use username-password flow.
2. You need to add the azure key vault permission to your app.
And do not forget grant admin consent for it.
3. Then you can refer to the code below to get the secret value.
const KeyVault = require('azure-keyvault');
const { AuthenticationContext } = require('adal-node');
const clientId = '<clientId>';
const username = '<username>';
const password = '<password>';
var secretAuthenticator = function (challenge, callback) {
var context = new AuthenticationContext(challenge.authorization);
return context.acquireTokenWithUsernamePassword(challenge.resource, username, password, clientId, function(
err,
tokenResponse,
) {
if (err) throw err;
var authorizationValue = tokenResponse.tokenType + ' ' + tokenResponse.accessToken;
return callback(null, authorizationValue);
});
};
var credentials = new KeyVault.KeyVaultCredentials(secretAuthenticator);
var client = new KeyVault.KeyVaultClient(credentials);
client.getSecret("https://<keyvaultname>.vault.azure.net/", "<secret name>", "<secret version>", function (err, result) {
if (err) throw err;
console.log("secret value is: " + result.value);
});

Is it possible to create a secret_id to use it in an approle automatically without the help of an administrator or kubernetes when using vault?

Recently searching the internet I found a good alternative to manage the secrets of my application created in node js with the help of hashicorp vault. I have investigated how it works and among the possible ways that this tool has to enter I found approle, which I consider an adequate form of authentication through my application. This form of authentication requires a role_id and a secret_id. The latter, as I see in the examples of the official vault page, needs an entity for its creation and then passes it to the application and in this way the application can receive the token to enter the vault. Currently I have this code in node js that receives a token wrapped with the secret_id to achieve access to the secrets with the role of the application:
//get the wrap token from passed in parameter
var wrap_token = process.argv[2];
if(!wrap_token){
console.error("No wrap token, enter token as argument");
process.exit();
}
var options = {
apiVersion: 'v1', // default
endpoint: 'http://127.0.0.1:8200',
token: wrap_token //wrap token
};
console.log("Token being used " + process.argv[2]);
// get new instance of the client
var vault = require("node-vault")(options);
//role that the app is using
const roleId = '27f8905d-ec50-26ec-b2da-69dacf44b5b8';
//using the wrap token to unwrap and get the secret
vault.unwrap().then((result) => {
var secretId = result.data.secret_id;
console.log("Your secret id is " + result.data.secret_id);
//login with approleLogin
vault.approleLogin({ role_id: roleId, secret_id: secretId }).then((login_result) => {
var client_token = login_result.auth.client_token;
console.log("Using client token to login " + client_token);
var client_options = {
apiVersion: 'v1', // default
endpoint: 'http://127.0.0.1:8200',
token: client_token //client token
};
var client_vault = require("node-vault")(client_options);
client_vault.read('secret/weatherapp/config').then((read_result) => {
console.log(read_result);
});
});
}).catch(console.error);
The problem is that I plan to upload the application in the cloud using docker and the idea is that the process of obtaining the secrets is automatic so I would like to know if when creating a token that lasts long enough that you only have the possibility of obtaining the secret_id of a role and saving it as environment variable is appropriate in this case or if there is any other alternative that can help me in automating this case.
Note: I don't plan to deploy in aws in this case.

Azure ADAL - How to get refresh token / how to refresh access token for nodejs backend server to server connection?

I'm using adal-node module for my Node JS backend to write file to Azure Storage. The authentication works fine, but the access token I got only valid for 1 hour. And so far I couldn't find anyway to refresh my access token. Can someone advise?
I've tried to get refresh token. But the auth function I'm using below don't send refresh token back. I've also try to just create a new token after a while using the same auth function, but it turns out the token is always the same.
Here's the code I use to get the access token.
var AuthenticationContext = require('adal-node').AuthenticationContext;
var authorityHostUrl = 'https://login.windows.net';
var tenant = 'myTenant.onmicrosoft.com'; // AAD Tenant name.
var authorityUrl = authorityHostUrl + '/' + tenant;
var applicationId = 'yourApplicationIdHere'; // Application Id of app registered under AAD.
var clientSecret = 'yourAADIssuedClientSecretHere'; // Secret generated for app. Read this environment variable.
var resource = '00000002-0000-0000-c000-000000000000'; // URI that identifies the resource for which the token is valid.
var context = new AuthenticationContext(authorityUrl);
context.acquireTokenWithClientCredentials(resource, applicationId, clientSecret, function(err, tokenResponse) {
if (err) {
console.log('well that didn\'t work: ' + err.stack);
} else {
console.log(tokenResponse);
}
});
Need some way to refresh my access token so that my long running job wouldn't stop.
Just get a new access token.
In the Client Credentials flow, a refresh token is not returned. (See Section 4.4.3 of the OAuth 2.0 spec.)

Resources