Uploading RootCA to apim via az cli - azure-powershell

Is there a function in the az cli which can perform the same operation via the Az Powershell module as documented here: https://learn.microsoft.com/en-us/powershell/module/az.apimanagement/new-azapimanagementsystemcertificate?view=azps-5.8.0#related-links
I've reviewed the API docs and it seems like you can only update Certificate vs System Certificate: https://learn.microsoft.com/en-us/rest/api/apimanagement/2020-06-01-preview/certificate/createorupdate#apimanagementcreatecertificate
Essentially I want to automate the process of uploading a CA Certificate to API Management Service - was hoping to avoid having to install Powershell to perform this task.

There is no such built-in equivalent for New-AzApiManagementSystemCertificate in Azure CLI, actually it is a wrapper to encode the certificate with base64 and integrate with the certificatePassword(can be omitted) and storeName, at last, it will get a CertificateConfiguration, then use New-AzApiManagement or Set-AzApiManagement to create/update the APIM, they essentially call the Api Management Service - Create Or Update RESt API.
So to do this in Azure CLI, you just need to use az rest to call the REST API directly.
First, use bash to base64 encode the certificate, in my test sample, it is a .cer certificate.
$ cat ./testapim.cer | base64 -w 0
Then pass it to the sample command below, modify the values with yours.
az rest --method put --uri https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<group-name>/providers/Microsoft.ApiManagement/service/joyapim?api-version=2019-12-01 --headers '{"Content-Type":"application/json"}' --body '{
"properties": {
"certificates": [
{
"encodedCertificate": "*******Base64 encoded Certificate******************",
"certificatePassword": "Password",
"storeName": "Root"
}
],
"publisherEmail": "xxxxx",
"publisherName": "xxxxx"
},
"sku": {
"name": "Developer",
"capacity": 1
},
"location": "Central US"
}'
Check the result in the portal:

Related

Connect to BigQuery with Service Account Credentials?

I create a Google service account to access BigQuery, it provides a .json credentials file, which looks like:
{
"type": "service_account",
"project_id": "<redacted>",
"private_key_id": "<redacted>",
"private_key": "-----BEGIN PRIVATE KEY-----<redacted>\n-----END PRIVATE KEY-----\n",
"client_email": "<redacted>",
"client_id": "<redacted>",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "<redacted>"
}
Using a secrets manager, I load the above into a Python dict bigquery_credentials, then try to connect:
client = bigquery.Client(credentials=bigquery_credentials)
I get the error:
DefaultCredentialsError: Could not automatically determine credentials. Please set GOOGLE_APPLICATION_CREDENTIALS or explicitly create credentials and re-run the application. For more information, please see https://cloud.google.com/docs/authentication/getting-started
Clearly, I'm not passing the credentials in a valid way and bigquery.Client isn't recognizing them.
The docs say "Set the environment variable GOOGLE_APPLICATION_CREDENTIALS to the path of the JSON file that contains your service account key."
I'd prefer to avoid using the file system. This code is running in an environment where I may not have access to the local file system. Also, I'm using a secret manager: storing secrets on the file system is considered a security risk.
Is there any way I can specify the service account .json credentials to bigquery.Client?
I just had this one, you can use the following:
from google.cloud import bigquery
client = bigquery.Client.from_service_account_json("/path/to/your/file.json")

GCP text-to-Speech API auth issue

I was trying the above api in postman. Here is the request json:
{
"input":{
"text":"Flutter is awesome!"
},
"voice":{
"languageCode":"en-gb",
"name":"en-GB-Standard-A",
"ssmlGender":"FEMALE"
},
"audioConfig":{
"audioEncoding":"MP3"
}
}
for auth, i chose Bearer in postman auth and first executed the following command in my terminal to get the token:
gcloud auth application-default print-access-token
i pasted this token in auth header, and i received the following response :
{
"error": {
"code": 403,
"message": "Your application has authenticated using end user credentials from the Google Cloud SDK or Google Cloud Shell which are not supported by the texttospeech.googleapis.com. We recommend configuring the billing/quota_project setting in gcloud or using a service account through the auth/impersonate_service_account setting. For more information about service accounts and how to use them in your application, see https://cloud.google.com/docs/authentication/. If you are getting this error with curl or similar tools, you may need to specify 'X-Goog-User-Project' HTTP header for quota and billing purposes. For more information regarding 'X-Goog-User-Project' header, please check https://cloud.google.com/apis/docs/system-parameters.",
"status": "PERMISSION_DENIED",
"details": [
{
"#type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "SERVICE_DISABLED",
"domain": "googleapis.com",
"metadata": {
"consumer": "projects/12345678910",
"service": "texttospeech.googleapis.com"
}
}
]
}
}
I am very new to GCP in general and don't know how to navigate this issue. For additional context, i am trying to make a REST API call where i send the text and get a base64encoded string containig audio back. Any help is appreciated.
This is confusing/complex but the error is helpful:
Your application has authenticated using end user credentials from the Google Cloud SDK or Google Cloud Shell which are not supported by the texttospeech.googleapis.com.
NOTE You can try this method using Google's APIs Explorer at this link
text.synthesize.
The issue is that gcloud is an OAuth2 application and tokens issued by gcloud either using gcloud auth print-[access|identity]-token and gcloud auth application-default print-access-token are issued against a Google-managed project (that Google provides for gcloud) and -- importantly -- not one of your own projects.
Google wants to provide gcloud for its users but does not want to provide arbitrary API access (for free) to its users. Hence the "not supported" part of the error.
The solution (as described) is that you should:
Use (or create) your own Google Project
Enable the Text-to-Speech service (API) in this project
Create a Service Account and key
gcloud auth activate-service-account providing the Service Account key
gcloud auth print-access-token to get an access token to invoke the API
See the following link for the steps:
https://cloud.google.com/text-to-speech/docs/libraries

How to configure key settings for IdentityServer in appsettings.json for aspnet core app running on IIS

I created the template Angular / ASP.NET Core with authorisation support using this command:
dotnet new angular --auth Individual
This is an:
ASP.NET Core 3.0 App with
ASP.NET Core Identity for authenticating and storing users,
IdentityServer4 for implementing Open ID Connect,
Angular SPA,
All pre-configured to work together.
Before I deploy my app based on this template, I'm trying to first deploy this template app to IIS.
I've deployed the app to IIS and have a database setup and the app connected to it just fine, but I'm stuck. I am not sure how to create and configure the production certificate to use for signing tokens.
At this point in the Microsoft docs it briefly mentions "A production certificate to use for signing tokens." and gives and example for deployment to Azure.
How do I create the key in IIS? do you do something here?
Then how do I then add the correct settings to appsettings.json?
"IdentityServer": {
"Key": {
"Type": "Store",
"StoreName": "My",
"StoreLocation": "CurrentUser",
"Name": "CN=MyApplication"
}
}
I'm struggling to find any guides or examples on the net, any help or point in the right direction would be appreciated.
I also found that the documentation is not comperhensive enough. I managed to deploy the an angular app to azure. Im not sure if it similar to the deployment to IIS. But may be this could help you to find the solution for your problem.
Deployment to Azure:
First you have to upload the (self signed) certificate (.pfx) to azure app service. I used this guide to create self signed certificate.
upload certificate image
You also have to make the certificate available by adding the thumbprint into the application setting. see image.
Dont forget to update your appsettings.json so your app can access the certificate from the previous step.
"IdentityServer": {
"Key": {
"Type": "Store",
"StoreName": "My",
"StoreLocation": "CurrentUser",
"Name": "CN=yourApp-domain.com"
}
}
If you encounter problem. Change the environtment variable in appservice to "Development" to see detail information of the error. like this.
change environment variable
For now I have worked around this problem by exporting the certificate to a file. Under Server Certificates in IIS you can right-click a certificate and export it.
Then you can configure the key parameters in appsettings.json to reference a file like so:
"Key": {
"Type": "File",
"FilePath": "..\\test.pfx",
"Password": "Test"
}
I would still like to reference a store certificate.
So this should fairly straightforward to configure for development purposes. In IIS you can issue yourself a self-signed certificate which will naturally only be valid on your local machine.
Give it some name and if you don't change anything else and click OK, it will by default store the generated certificate in your Personal store for LocalMachine so below config should work:
"IdentityServer": {
"Key": {
"Type": "Store",
"StoreName": "Personal",
"StoreLocation": "LocalMachine",
"Name": "YourName"
}
}
It is worthwhile noting that if you try to import certificate from somewhere else - it must be at least 2048 bit key for Identity Server 4 purposes.
Create a new certificate in Powershell as Administrator if you don't have a certificate already:
New-SelfSignedCertificate -DnsName "blazortest" -CertStoreLocation "cert:\CurrentUser\My"
I then used mmc.exe to export the certificate as a .pfx file.
If you host on IIS you need to import the .pfx certificate to the Personal folder for Local Computer and then select Manage Private Keys... and give access to the user running the Application Pool.
Complete answer from other thread with IdentityServerBuilderConfigurationExtensions publish exception:
https://stackoverflow.com/a/66448397/3850405

Is it possible to access the Google Cloud Scheduler API using an API key?

Is it possible to access the Google Cloud Scheduler API using an API key?
Method: projects.locations.jobs.create
https://cloud.google.com/scheduler/docs/reference/rest/v1/projects.locations.jobs/create
I am trying to create a Job using curl:
curl -X POST \
'https://cloudscheduler.googleapis.com/v1/projects/my-project/locations/nam5/jobs?key=[MyAwesomeAPIKey]' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"name": "test-awesome-job",
"description": "My first job",
"schedule": "45 23 * * 6",
"timeZone": "utc",
"pubsubTarget": {
"topicName": "projects/my-project/topics/topic-name",
"attributes": {
"name": "39ro"
}
}
}'
but it result in a 401 Unauthorized response:
"error": {
"code": 401,
"message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"status": "UNAUTHENTICATED"
}
The Cloud Scheduler API uses service account credentials as described in https://cloud.google.com/docs/authentication/production. As the API docs state, a limited number of GCP services support API keys and that does not include Cloud Scheduler.
If you are running the code to interact with the Cloud Scheduler API on App Engine, Cloud Functions, or Cloud Run the service account is built-in and all you need to do is grant that service account permission to interact with Cloud Scheduler via IAM.
The docs have some more streamlined information on getting set up with the Cloud Scheduler client libraries.
I get confused watching the API explorer which suggested as possible credentials
Google OAuth 2.0 or API key and from the "Help me choose" tool from Google Cloud API credentials (https://console.cloud.google.com/apis/credentials), which apparently now reports the correct solution:
For your situation you can use Application Default Credentials,
which provide a simple way to access Google APIs from App Engine or Compute Engine.
previously it showed the API keys as a possible option.
Thanks #Grayside for pointing me out!

ERROR: (gcloud.auth.activate-service-account) Failed to activate the given service account. Please ensure provided key file is valid

I'm trying to follow this guide https://cloud.google.com/speech/docs/getting-started to call GAE speech to text api through curl. But it doesn't seem to work.
I've setup a project and enabled speech to text api. But then when I try to active the service account it fails. I've run diagnostics, tried different accounts, verified the json file (has email), tried gcloud beta init :-(
bash-3.2$ gcloud auth activate-service-account account#project.iam.gserviceaccount.com --key-file=project.json
ERROR: (gcloud.auth.activate-service-account) Failed to activate the given service account. Please ensure provided key file is valid.
The next step though 'gcloud auth print-access-token' returns a token.
But the final step (curl) returns this -
{
"error": {
"code": 403,
"message": "Google Cloud Speech API has not been used in project google.com:cloudsdktool before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/speech.googleapis.com/overview?project=google.com:cloudsdktool then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.",
"status": "PERMISSION_DENIED",
"details": [
{
"#type": "type.googleapis.com/google.rpc.Help",
"links": [
{
"description": "Google developers console API activation",
"url": "https://console.developers.google.com/apis/api/speech.googleapis.com/overview?project=google.com:cloudsdktool"
}
]
}
]
}
}
The problem seems to lie in the project(google.com:cloudsdktool instead of mine) used to authenticate the incoming request.
I'm guessing the call to activate-service-account is causing this?
You are getting the error message for google.com:cloudsdktool project because the command you ran with curl gcloud auth print-access-token was using your user account credentials (created by gcloud auth login) and not service account (as you point out that step failed for you).
The command to activate service account is correct (btw you do not need to provide the account, as one from the file will be used)
$ gcloud auth activate-service-account --key-file=project.json
Make sure your project.json is correct file in the right format format. You can create this json key file either in
in https://console.cloud.google.com/iam-admin/serviceaccounts/project?project=YOUR_PROJECT_NAME
gcloud iam service-accounts keys create, see reference guide.
The file will look like
{
"private_key_id": "....",
"private_key": "-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----\n",
"client_email": "...",
"client_id": "...",
"type": "service_account"
}
Note that client_email will be used for ACCOUNT in activate-service-account command.