during the node start (hard hat) I'm able to read the accounts and private keys.
I don't understand how can I retrieve it again with hard hat console
npx hardhat console
I injected even web3 library but I'm able to retrieve only the addresses.
web3:
await web3.eth.getAccounts()
ethers.js
[owner, addr1] = await ethers.getSigners()
Private keys, even of unlocked accounts, are not shared over the JSON-RPC API.
Which means, you are not able to retrieve them using web3js, ethers.js, or any other wrapper of the API.
Related
I have a Firebase (node.js) cloud function that pulls in some data from my app's Firestore database and builds some static content for the web. I'd like that same cloud function to deploy the static content to Firebase hosting via the Firebase Hosting API, creating a static portion of my site with user generated content.
I understand the general flow thanks to the somewhat clear walkthrough, but am stuck on the first step: getting an access token to call the API. Obviously I'm not going to insecurely put my service account key in the cloud function itself, so the example in the walkthrough doesn't apply. And as I understand it, Firebase cloud functions are already associated with a service account, so presumably there's some way to get an access token to call other Google Cloud services from a cloud function.
So how do I get an access token to call the hosting API from a Cloud Function?
There are some red flags that make me think this isn't possible. For example, all of the uses cases in the walkthrough allude to other server environments, as opposed to Google Cloud environments. And yet, this use case is the third bullet in the use case list in the walkthrough.
I've searched extensively here and elsewhere for some guidance, but aren't finding anything. There are some older questions about accessing hosted files from a cloud function that aren't relevant. This promising question from 5 years ago about this exact use case only has dead ends.
You can use the google-auth-library package in Cloud Functions to a get a token as shown below:
import { GoogleAuth } from "google-auth-library";
const token = await new GoogleAuth({
scopes: ["https://www.googleapis.com/auth/cloud-platform"],
}).getAccessToken();
If you use Firebase Admin SDK in the Cloud Functions, then you can get an access token of the default service account as shown below (do ensure the service account has required permissions):
import { initializeApp } from "firebase-admin/app";
const admin = initializeApp();
const token = await admin.options.credential?.getAccessToken();
// ^ Google OAuth2 access token object used to authenticate with Firebase services.
I am trying to use the service account using Google Cloud Functions to access the Workspace Directory API. I am trying to use Application Default Credentials approach. Since the documentation doesn't mention any additional steps to be done in the Google Cloud Console side, I assume that Application Default Credentials (ADC) to the function is automatically passed to the cloud function from Google Cloud's Metadata server. The following code works perfectly in my local, emulated environment where I have set GOOGLE_APPLICATION_CREDENTIALS environment variable to point to the JSON credential file. However when I deploy the function to Google Cloud, I am getting the error "Not Authorized to access this resource/api". I have been searching and trying for days without any success. As an aside, before I stumbled upon this thread, I was using getCredentials() method of GoogleAuth to get the private_key to create JWT auth (for the "subject" property) and passing that auth to admin API call. Which again worked perfectly in my local environment but fails in the cloud environment because getCredentials() private_key is null, which is probably expected behavior. Any help is deeply appreciated. I am inexperienced with posting in Stackoverflow, if I need to follow any other protocol, please advise.
export const listUsers = functions.https.onCall((data, context) => {
return new Promise(async (resolve, reject) => {
const envAuth = new GoogleAuth({
scopes: ["https://www.googleapis.com/auth/admin.directory.user.readonly"],
clientOptions: {
subject: "admin#mydomain.com",
},
});
const client = await envAuth.getClient();
const service = google.admin({version: "directory_v1", auth: client});
try {
const response = await service.users.list({
customer: "MYCUSTOMER_ID",
});
resolve(response);
} catch (err) {
reject(err);
}
});
});
When you run a Cloud Function without authenticating via a key file (the json credential file that has the key to allow you to impersonate/authenticate as a different user), the function runs as the default application credentials for the project (<YOUR_CLOUD_PROJECT_ID>#appspot.gserviceaccount.com). You don't have to do anything special, no authentication calls -- it runs with the permissions of this service account by default.
When you run the code locally, it takes on the user authentication of whatever key file you have locally (and have referenced in the "GOOGLE_APPLICATION_CREDENTIALS" environment variable on your machine).
Without full security information on your environment, it's hard to know for sure... But, I'm guessing that you're trying to access resources that your personal Google Account has proper access; however, the default service account for you Cloud Functions Project does not.
So, couple of routes to troubleshoot and/or fix the issue:
Give the default service account access rights to Workspace resource(s) you're attempting to access.
Use the JSON key file you setup locally already, to have the Cloud Function run as the same user as is happening when you run locally.
Essentially do a hybrid where you create a new service account that ONLY has the permissions you want (instead of using the default service account or your personal user, both of which might have far more permissions then desired for safety/security), use a key file to run the Cloud Function under that identity, and only give the desired permissions to that service account.
I integrated spring cloud gateway with oauth2 login. After logout in scg, the user still can access resource server because the user has valid token. I need to invalidate this valid token in some way. there is blacklist solution as my researches (https://stackoverflow.com/a/53994938/5079581) and i will implement this.
by creating filter, i take jwt in step of "/logout" and put it to blacklist.
public class ExampleWebFilter implements WebFilter {
#Override
public Mono<Void> filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {
ServerHttpRequest request = serverWebExchange.getRequest();
String uri = request.getPath().pathWithinApplication().value();
HttpHeaders headers = request.getHeaders();
if(uri.equals("/logout")) {
List<String> auth = headers.get("Authorization");
}
return webFilterChain.filter(serverWebExchange);
}
}
auth list always returns null. i think that my filter works before token relay filter. how can i access the jwt at gateway? is there any code sample or demo for this? Thanks.
In spring cloud gateway + security oauth2 integration, JWTs are stored in gateway as session. At first, i thought there was an error about saving JWT as session, as it becomes stateful. But, when you logged out, this session is removed and there is no JWT anymore, so there is no need to create blacklist. this way of working is a clever solution.
So, what was my problem? I had 2 seperate servers (gateway, oauth2 server). two sessions are created as a result of the operation. SESSION for gateway, JSESSION for oauth2 server. when you logged out at gateway, only SESSION is removed, but JSESSION is still alive. because of that, the gateway goes oauth server(and still signed in oauth2 server) and get new JWT.
To log out completely in system, you also need to logged out from ouath2 server at the same time.
I have a Function in Azure, which has MSI (Managed Service Identity) enabled which I am trying to use to access an Azure based WebAPI (App Service WebApp) which in turn has Azure AD Authentication enabled (all same Azure Directory).
My WebAPI has an Azure App registered so it can use AAD Authentication.
This app also has the necessary AppRoles configured in its Manifest (for types 'User' and for 'Application').
I have also verified that the Functions Identity (app) was successfully created in Azure AD when I enabled MSI on the Function.
When I try to obtain a token within my Function using MSI i receive a 400 Bad Request response / error:
"ExceptionMessage": "AADSTS50105: Application '###' is not assigned to a role for the application '###'
"ErrorCode": "invalid_grant"
I have ensured the Resource value I pass in is my webAPIs app ID URI.
string resource = "<My App URI>";
string apiversion = "2017-09-01";
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Secret", Environment.GetEnvironmentVariable("MSI_SECRET"));
var r = await client.GetAsync(String.Format("{0}/?resource={1}&api-version={2}", Environment.GetEnvironmentVariable("MSI_ENDPOINT"), resource, apiversion));
return r;
But I still get the same error. The code for requesting a token is fine, and the error does infact point towards a permissions issue.
The one thing I have not been able to do (and I guess this is the problem) is find a way to give add the new MSI/Function Identity to the Users & Groups of the webAPIs Azure App. No matter what I try my Functions App Identity does not appear in the Users list when I search for it to add as a member of the webAPI app (with the Application role).
Does anyone have any suggestions as to why I cannot add the Functions MSI to an Apps Users & Groups or to an Azure AD Group?
Or am I doing something else wrong perhaps?
Juuna was spot on in his response to my original post:
When enabling MSI on a service only a Service Principal is created in Azure AD and as such this wont appear in search results when trying to add the SP as a member of a Group or to User & Groups of an Azure AD App.
In order to assign your MSI created Service Principal permissions to your App you need to:
Edit your apps manifest and ensure you have app roles with allowed member type = "Application"
Run the PowerShell cmdlet "New-AzureADServiceAppRoleAssignment (link) to grant your Service Principal the Application role you added to your apps manifest
Within your MSI enabled service re-try requesting a token
For me, following the above, I can now successfully request app tokens from my Function so my same Azure Function can call my WebApp (which is AAD Authentication enabled).
In fact, when you enable MSI, it will create a service principal(not a user), so you could not find it in Users&Groups.
You could find it on Azure Portal and try to give permissions you need. Azure Active Directory -->Enterprise applications
Note: The service principal name is same with your function name.
In function, you should use the following code to get token, please refer to this link.
using Microsoft.Azure.Services.AppAuthentication;
using Microsoft.Azure.KeyVault;
// ...
var azureServiceTokenProvider = new AzureServiceTokenProvider();
string accessToken = await azureServiceTokenProvider.GetAccessTokenAsync("https://management.azure.com/");
// OR
var kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
I'm unable to get my Google Compute instance to speak to the Datastore (within the same project).
I believe I've set everything up correctly:
Google Compute instance has the full API scope
All the relevant APIs have been enabled in the project
Billing is enabled in the project
The tutorials claim that I won't even need to have a service account to use the API, but since it didn't work I also tried setting up a service account and put the key file on my instance. Still no luck.
Here's the code I'm trying to run (I created a Test entity in the Datastore of the project, and I can successfully look it up using Google's API explorer with an OAuth2 token for my account):
const gcloud = require('gcloud')({
projectId: 'roger-web-client',
keyFilename: './roger-web-client-8d1fbd8baae2.json',
});
const dataset = gcloud.datastore.dataset();
dataset.get(dataset.key(['Test', 5629499534213120]), (error, entity) => {
console.log(error || entity);
});
This results in the error 403 Forbidden. If I comment out keyFilename, I get 401 Unauthorized instead, which seems to imply the magic authorization on Google Compute instances isn't working for me.
Ideas?