AuthenticationContext.AcquireTokenAsync without creds: only works in Console App - jwt

I have a test console app that successfully retrieves a cert from the local computer Cert store and use this cert to get a token from AAD.
However, when I run this inside of a Windows service, AcquireTokenAsync() does not run and breaks the execution, although the cert is retrieved from the store.
I did notice a private key error : PrivateKey = '_certCred.Certificate.PrivateKey' threw an exception of type 'System.Security.Cryptography.CryptographicException'
Any advice would be helpful

It would be good if we have a source code and information about the accounts you are using so we can see where the certificate is stored, but based on your description:
It is possible that the user on which the service account is running does not have access to the certificate you are trying to access.
One possibility is to configure the service to run as System Account and then select the 'Allow the service to interact with Desktop'.

Related

Service Fabric, Azure Devops Deployment fails : The specified network password is not correct

I was recently ordered by our IT team to disable the NAT pools on my service fabric cluster due to security risks. The only way I could do this was to deploy a new cluster with all its components.
Because this is a test environment I opt to use a self signed cert without a password for my cluster, the certificate is in my vault and the cluster is up and running.
The issue I have now is when I try to deploy my application from an Azure Devops Release Pipeline I get the following message:
An error occurred attempting to import the certificate. Ensure that your service endpoint is configured properly with a correct certificate value and, if the certificate is password-protected, a valid password. Error message: Exception calling "Import" with "3" argument(s): "The specified network password is not correct.
I generated the self signed certificate in Key Vault, downloaded the certificate and used Powershell to get the Base64 string for the service connection.
Should I create the certificate myself, with a password?
With the direction of the two comments supplied, I ended up generating a certificate on my local machine using the powershell script included with service fabric's local run time.
A small caveat here is to change the key size in the script to a large key size than the default, because ke vault does not support 1024 keys.
I then exported the pfx from my user certificates added a password(this is required for the service connection) and impoted the new pfx into my key vault.
Redeployed my cluster and it worked.

Deploying a Service fabric app from Team Services to Azure

I need some help with deploying a Service fabric app from Team Services to Azure.
I’m getting the following error from the Agent in Team Services (see screenshot below):
2018-06-22T13:17:13.3007613Z ##[error] An error occurred attempting to
import the certificate. Ensure that your service endpoint is
configured properly with a correct certificate value and, if the
certificate is password-protected, a valid password.
Error message: Exception calling "Import" with "3" argument(s):
"Cannot find the requested object.
Please advise.
Here is my Service Fabric Security security page, don't remember where I set up the password needed on the VSTS side but I took note of it and believe it's correct.
Here is the Endpoint page on the VSTS side:
Issue resolved with the help of MS Support by creating a new Certificate in the Key Vault and Adding it to the Service Fabric, steps:
Azure Portal:
Home > Key vaults > YourKeyVault - Certificates: Generate/Import
Generate new key with a CertificateName of your choosing and CN=CertificateName as Subject.
Home > Key vaults > YourKeyVault - Certificates > CertificateName
Select the only version available and Download in PFX/PEM format.
Power Shell: Convert to Base64 string, CertificateBase64
[System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes("c:\YourCertificate.pfx"))
Home > YourServicefabric - Security: Add
Add the Certificate you created as Admin Client by providing 's thumbprint.
VSTS/TFS:
Build and release > Your pipeline: Edit
In the Deployment Process Service Fabric Environment click Manage for Cluster Connection and add a new connection. Besides the other information, in the Client Certificate paste the previous CertificateBase64.
Check the Service Endpoint in VSTS:
Whether it has a properly base64 encoded certificate, with a private key.
Also, check if the provided passphrase is correct.
Also, check if the service endpoint is configured as tcp://mycluster.region.cloudapp.azure.com:19000.
Check if the thumbprint is correct.

Google Cloud Storage 500 Internal Server Error 'Google::Cloud::Storage::SignedUrlUnavailable'

Trying to get Google Cloud Storage working on my app. I successfully saved an image to a bucket, but when trying to retrieve the image, I receive this error:
GCS Storage (615.3ms) Generated URL for file at key: 9A95rZATRKNpGbMNDbu7RqJx ()
Completed 500 Internal Server Error in 618ms (ActiveRecord: 0.2ms)
Google::Cloud::Storage::SignedUrlUnavailable (Google::Cloud::Storage::SignedUrlUnavailable):
Any idea of what's going on? I can't find an explanation for this error in their documentation.
To provide some explanation here...
Google App Engine (as well as Google Compute Engine, Kubernetes Engine, and Cloud Run) provides "ambient" credentials associated with the VM or instance being run, but only in the form of OAuth tokens. For most API calls, this is sufficient and convenient.
However, there are a small number of exceptions, and Google Cloud Storage is one of them. Recent Storage clients (including the google-cloud-storage gem) may require a full service account key to support certain calls that involve signed URLs. This full key is not provided automatically by App Engine (or other hosting environments). You need to provide one yourself. So as a previous answer indicated, if you're using Cloud Storage, you may not be able to depend on the "ambient" credentials. Instead, you should create a service account, download a service account key, and make it available to your app (for example, via the ActiveStorage configs, or by setting the GOOGLE_APPLICATION_CREDENTIALS environment variable).
I was able to figure this out. I had been following Rail's guide on Active Storage with Google Storage Cloud, and was unclear on how to generate my credentials file.
google:
service: GCS
credentials: <%= Rails.root.join("path/to/keyfile.json") %>
project: ""
bucket: ""
Initially, I thought I didn't need a keyfile due to this sentence in Google's Cloud Storage authentication documentation:
If you're running your application on Google App Engine or Google
Compute Engine, the environment already provides a service account's
authentication information, so no further setup is required.
(I am using Google App Engine)
So I commented out the credentials line and started testing. Strangely, I was able to write to Google Cloud Storage without issue. However, when retrieving the image I would receive the 500 server error Google::Cloud::Storage::SignedUrlUnavailable.
I fixed this by generating my private key and adding it to my rails app.
Another possible solution as of google-cloud-storage gem version 1.27 in August 2020 is documented here. My Google::Auth.get_application_default as in the documentation returned an empty object, but using Google::Cloud::Storage::Credentials.default.client instead worked.
If you get Google::Apis::ClientError: badRequest: Request contains an invalid argument response when signing check that you have dash in the project name in the signing URL (i.e projects/-/serviceAccounts explicit project name in the path is deprecated and no longer valid) and that you have "issuer" string correct, as the full email address identifier of the service account not just the service account name.
If you get Google::Apis::ClientError: forbidden: The caller does not have permission verify the roles your Service Account have:
gcloud projects get-iam-policy <project-name>
--filter="bindings.members:<sa_name>"
--flatten="bindings[].members" --format='table(bindings.role)'
=> ROLE
roles/iam.serviceAccountTokenCreator
roles/storage.admin
serviceAccountTokenCreator is required to call the signBlob service, and you need storage.admin to have ownership of the thing you need to sign. I think these are project global rights, I couldn't get it to work with more fine grained permissions unfortunately (i.e one app is admin for a certain Storage bucket)

Deploy a business network on bluemix

I use this tutorial to deploy a business network on a free bluemix cluster: https://ibm-blockchain.github.io/
I also deploy the REST Server and communicate via Web apps.
All went fine till yesterday. The REST Server was not accessible anymore.
I deleted everything on the cluster using the script delete_all available in the ibm-container-service repository.
I followed the install procedure using the create_all script. I could access the composer playground (port 31080) again but was not really able to deploy an online business network using the "profile" hlfv1. Now it asks at the bottom of the "deploy UI" for credentials.
I don't know what to fill in. I tried to use ID+Password. On this way I was able to deploy but I got access error by clicking on "connect now". I was able to start the REST server then but if i try to access it in the browser (port 31090), I get the feedback that I'm not authorized.
Any ideas?
And do you know which changes have been made in the last month, which could bring these troubles?
Thx
Phil
The tutorial pointed to only covers playground when used with a Web Browser connection not a real fabric. When you deploy to a real fabric you have to provide an initial identity that you want bound to an initial participant in the business network. The initial participant will be of type org.hyperledger.composer.system.NetworkAdmin and given a name of the initial identity name you provide.
This dialog looks like this
To get you started you should select the ID and Secret radio button. Then for Enrollment ID enter admin and for the Enrollment Secret enter adminpw.
This is the name and secret of the bootstrap identity that exists in the fabric-ca server that has been deployed as part of the scripts.
By providing this information that identity will be enrolled and it's public certificate will be bound to a NetworkAdmin participant which will be called admin. This identity admin will then have access to the business network as only identities that are bound to a participant in the business network can have any sort of access.

Azure Service Fabric, KeyVault, SSL Certificates

I want to secure my own HTTPS end point (node.js express.js server) with a certificate which I have deployed to the cluster (that is, it exists in Cert:\LocalMachine\My).
I of course want to avoid having my certificate in source control. I can't use an EndpointBindingPolicy in the ServiceManifest because as far as I'm aware that is just for http.sys(?) based systems, which this isn't.
What I thought is perhaps run a SetupEntryPoint script to:
grab the certificate from the store
export it as a pfx with a random passphrase (or some appropriate format)
copy it to {pkgroot}/certs/ssl_cert.pfx
replace some sort of token in serverinit.js with the random passphrase
This way the server, er, code base doesn't need to have the certificate present, i just needs to trust that it will be there when the service is run.
However I don't think I can do this, if it even is as sensible idea, as the certificates in the store are marked such that the private key is non-exportable! Or, at least, they are with my RDP account!
Is there a way to export the certificate with its private key?
What are my options here?
I ended up writing a powershell script which runs in my release pipeline, arguments are clientID, clientSecret and certificateName. clientSecret is stored as a protected environmental variable for my agent.
Create new application registration under same subscription as KeyVault (which should be same as SF Cluster) (e.g. in portal.azure.com)
Note down app ID
Create app secret
Modify KeyVault ACL with App as principal, set get only on secrets
use REST api with client ID and secret https://learn.microsoft.com/en-us/rest/api/keyvault/getsecret
I chose this over grabbing the certificate in the SetupEntryPoint, for example, as this hides the client secret better from the open world (e.g. developers who shouldn't/don't need access to it)