Publishing .NET Core Web API (FIDO2 WebAuthn Passwordless) to Azure

In the previous post, we created a FIDO2 and WebAuthn .NET Core WebApi as a separate project (back end) and a separate NextJs project as a front end app in order to log in with no password. The previous two projects ran on localhost. They can be found in this blog post:

In this blog post, we will prepare, and publish the .NET Core part project to Azure.

First of all, we have to store our MongoDb connection string in Azure Vault. We will need to create the following resources in Azure first, and in the following sequence as well. KeyVault will store the secret and the rest is also needed to publish the API and host it in Azure:

  • Resource Group
  • AppService Plan
  • Web App
  • KeyVault

Create Resource Group:

az group create --name yourchosennamerg --location "EastUs

Create an App Service plan

az appservice plan create --name yourchosenserviceplanname --resource-group yourchosennamerg  --sku FREE

Create a Web App

az webapp create --resource-group yourchosennamerg --plan yourchosenserviceplanname --name webappname

Create AzureKeyVault

az keyvault create --name "yourchosenkeyvaultname" --resource-group "yourchosennamerg " --location "EastUs"

Create managed identity

az webapp identity assign --name "yourwebappname" --resource-group "yourchosennamerg "

From the above commands, you will see the following returned:

{
 "principalId": "990e548b-a928-4f51-8c7e-9k75648h",
  "tenantId": "3a91548b-8c7e-a928-9ca5-3a91548b",
  "type": "SystemAssigned",
  "userAssignedIdentities": null
}

Grab the principalId and use it to assign the managed identity in order to give your web app permission to do get and list operations on your key vault, pass the principalId to the az keyvault set-policy command:

Assign Managed Identity

az keyvault set-policy --name "yourkeyvaultname" --object-id "990e548b-a928-4f51-8c7e-9k75648h" --secret-permissions get list

Now either from the code or inside Azure Portal, navigate to newly created KeyVault and add the MongoDb connection string as key value pair:

Alternatively, we can use PowerShell to create all the needed resources above right from command line. Copy the code below all of it into powershell and all the needed resources will be created:

#Connect to your Azure subscription if you are not already connected
Connect-AzAccount

# Create a resource group
New-AzResourceGroup -Name "rgpasswordless" -Location "EastUs"

# Create an App Service plan
New-AzAppServicePlan -Name "passwordlessserviceplan" -ResourceGroupName "rgpasswordless" -Location "EastUs" -Tier Free

# Create a web app
New-AzWebApp -ResourceGroupName "rgpasswordless" -AppServicePlan "passwordlessserviceplan" -Name "passwordlessapicorenext"

# Create a key vault
New-AzKeyVault -Name "PasswordlessKeyVault" -ResourceGroupName "rgpasswordless" -Location "EastUs"

# Assign a managed identity to the web app
Set-AzWebApp -AssignIdentity $true -Name "passwordlessapicorenext" -ResourceGroupName "rgpasswordless"

#Get PrincipalID
$principalId = (az webapp identity show --name "passwordlessapicorenext" --resource-group "rgpasswordless" | ConvertFrom-Json).principalId

#Set keyvaule access policy
Set-AzKeyVaultAccessPolicy -VaultName "PasswordlessKeyVault" -ObjectId $principalId -PermissionsToSecrets get,list

#Set the required secret in keyvault
$secretValue = ConvertTo-SecureString -String "YOURMONGODBCONNECTIONSTRING" -AsPlainText -Force
Set-AzKeyVaultSecret -VaultName "PasswordlessKeyVault" -Name "MongoDbConnString2" -SecretValue $secretValue

In the solution itself, and in terminal, bash or powershell, run the following commands to add the references to the API project in order to use KeyVault itself:

dotnet add package Azure.Identity
dotnet add package Azure.Security.KeyVault.Secrets

Then at the top of RegisterController, add using statements

using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
using Azure.Core;

After this we can use the following code block to replace the MongoDb connection string with Azure Key Vault secret, which is considered as a global variable in Azure. We can also write a helper method or database access layer in our API and add this code once. For the purpose of this demo, I put all the code in a single file.

SecretClientOptions options = new SecretClientOptions()
    {
        Retry =
        {
            Delay= TimeSpan.FromSeconds(2),
            MaxDelay = TimeSpan.FromSeconds(16),
            MaxRetries = 5,
            Mode = RetryMode.Exponential
         }
    };
var client = new SecretClient(new Uri("https://PasswordlessKeyVault.vault.azure.net/"), new DefaultAzureCredential(),options);

KeyVaultSecret secret = client.GetSecret("MongoDbConnString2");

string secretValue = secret.Value;

The next step is to switch to our terminal inside VSCode and publish our API locally:

dotnet publish -c Release -o ./publish

This will create a publish directory inside our API. Then, right click on the publish folder and navigate to Deploy To Web App

In the output tab of bottm panel in VSCode you will see these lines at the end of deployment:

9:44:08 PM passwordlessapicorenext: Copying file: 'publish\publish\web.config'
9:44:08 PM passwordlessapicorenext: Deleting app_offline.htm
9:44:08 PM passwordlessapicorenext: Finished successfully.
9:44:08 PM passwordlessapicorenext: Running post deployment command(s)...
9:44:08 PM passwordlessapicorenext: Triggering recycle (preview mode disabled).
9:44:09 PM passwordlessapicorenext: Deployment successful.
9:44:17 PM: Deployment to "passwordlessapicorenext" completed.

Then, navigate to your Azure Portal, and to your subscription ofcourse, then click on your WebApp and copy the Default Domain value. In my case it is: passwordlessapicorenext.azurewebsites.net

Add https://, and add swagger at the end of URL, so it becomes like this: https://passwordlessapicorenext.azurewebsites.net/swagger

Click enter and you should be able to see the swagger page with available API endpoints:

If you get 500.30 In-Process Startup Failure error open console inside your WebApp as below:

When the console opens, type:

dotnet dotnetcore-passwordless.dll

The name of the dll you can find it in publish directory locally when we published the API locally:

If everything is ok, you should see turning circle that never stops. Most of the startup errors should appear here in console, very detailed:

Another way to deploy this API would be by packaging everything to Acure Container Registry and adding our image to Azure Container Instance with the help of Docker.

Thank you.

How to create Salesforce Case in REST and WSDL using Salesforce API

Source code on Github:

REST

https://github.com/thoughtsonprogramming/SALESFORCE_REST_create_case

WSDL

https://github.com/thoughtsonprogramming/SALESFORCE_WSDL_create_case

We can create Cases in Salesforce in two different ways. One is using REST API, and call the POST method at the endpoint that Salesforce has provided, pass required parameters, and create a Case.

The other one is using WSDL, and SOAP, as web services, and use their exposed methods and API.But to use the WSDL API,we need to download physically to our machine WSDL FILE from Salesforce, store it on a disk, and add reference to it locally to our Visual Studio Solution.There is no online link to the web service where you can simply point your discovery tool and see all the methods exposed.

1

When using REST call, it depends which Salesforce Account you have opened. For authentication, and if you are on Sandbox Account of your company, you need to use:

https://test.salesforce.com/services/oauth2/token

On the other hand if you have a developer Salesforce Account, and to authenticate successfully with oauth,you need to use:

https://login.salesforce.com/services/oauth2/token

As well, and it is a necessity,if you are using REST API to authenticate yourself and then create a case, then you need to create a Connected App.

If you are on a sandbox account under your company, next to your logged in name, click on setup. Under Quick Links below, then under App, click on Manage Apps. Scroll to the bottom and you will see the heading Connected Apps, to the right of it there is New button. Click on it to create new connected app for oAuth REST authentication purposes.

You will be presented with a form, with red horizontal bars, meaning they are required.Filling only the required ones is enough.

-Connected App Name: Any Name you want for your app.

-API Name: You can put it same as Connected App Name.

-Contact Email: Same as your log in email.

Next Section would be API (Enable OAuth Settings)

Check the checkbox labelled “Enable OAuth Setttings”

For Callback URL, put any dummy web address starting with https. Ex: https://mydummysite.com

In Selected OAuth Scopes multiselect, choose Access and manage your data(api),and add it to Selected OAuth Scopes empty multi select by pressing Add button.

Leave it checked or check the checkbox labeled “Require Secret for Web Server Flow

Hit save button below.

You will see a message:”Allow from 2-10 minutes for your changes to take effect on the server before using the connected app.” Press continue button, and you will be presented of the Settings page for our newly created app. Note down those two fields under API (Enable OAuth Settings), Consumer Key and Consumer Secret.

Next we need to first reset our security token, and note it down. First head to Your Name at top right, then My Settings, then Personal item to the left, then click on Reset My Security Token, and click on the button with name “Reset Security Token”.

The new security token will be sent to your email. Write it down too.

At this point, we have everything we need to write REST call using c# to create a new case.

The response after successful oAuth authentication and authorization at Salesforce should look something like that:

REST_user_authenticated

Our REST app will have to be divided into two parts. First part will call one Salesforce endpoint to authenticate and authorize ourselves. The next part, will call another REST endpoint POST method to create new case.

After you create a new Case in Salesforce using REST, the response should look something like that:

case_created_response

If you noticed, there is a word “Created”

Please note, when using REST HTTP calls to create a new case in Salesforce, we are not using any downloadable separate libraries from Salesforce, or any SDKs, or from anywhere else.It is only HTTP, C#, https endpoints on Salesforce servers, and that’s it. This is very important to remember because the next way, as this posts Title says, will deal with WSDL and SOAP.

Also you will have to install DeveloperForce.Force and Newtonsoft.Json packages from NuGet, in order to create a new Case:

DeveloperForce_NewtonsoftJson

After you create a case, and log in to your developer, for example, Salesforce account, you should see the following cases below as such:

salesforce_new_cases

2

The second way to create a case in Salesforce is by using traditional web services. The only difference is that Salesforce rules say that you need to download particular WSDL, depending what API you want to work with, and integrate it in your development environment, which is Visual Studio and C#. In our case we need the enterprise WSDL.

In our sandbox environment, under our company, let’s click on setup beside our login name, and in Quick Find/Search, type api. Below, under Build section, there is Develop section, and beneath it is API link. Click on it, and a page win title API WSDL is opened to the right with the following WSDLs:

api-selections-list

-Enterprise WSDL

-Partner WSDL

-Apex WSDL

-Metadata WSDL

-Tooling WSDL

-Delegated Authentication WSDL

-Client Certificate

-Enterprise Package Version Settings

-Partner Package Version Settings

Select Enterprise WSDL and beneath it click on Generate Enterprise WSDL.

You will see in the next screen that you can choose the API versions that you want .We will keep the default, which is the latest ones. Click generate.

API-SF-SELECT

This will download or open an XML file. Save it in accessible directory, we will add it as service reference to our WSDLCreateSfCase project.

After you add this reference, you will be able to generate new cases on developer Salesforce account as well.

After successful login you should see something like this:

wsdl_login_success

And, after creating a case, using WSDL, you should see something like this:

wsdl_case_creation_success

Thank you