update according to comments

This commit is contained in:
zedy
2023-03-27 13:34:34 +08:00
parent bd9b6181d1
commit 0c13ff9e53
6 changed files with 19 additions and 156 deletions

View File

@@ -12,7 +12,7 @@
<PackageVersion Include="Ardalis.ListStartupServices" Version="1.1.4" />
<PackageVersion Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.0" />
<PackageVersion Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.2.1" />
<PackageVersion Include="Azure.Identity" Version="1.6.0" />
<PackageVersion Include="Azure.Identity" Version="1.9.0-beta.2" />
<PackageVersion Include="BlazorInputFile" Version="0.2.0" />
<PackageVersion Include="Blazored.LocalStorage" Version="4.3.0" />
<PackageVersion Include="BuildBundlerMinifier" Version="3.2.449" PrivateAssets="All" />

View File

@@ -63,20 +63,28 @@ powershell -ex AllSigned -c "Invoke-RestMethod 'https://aka.ms/install-azd.ps1'
curl -fsSL https://aka.ms/install-azd.sh | bash
```
And you can also install with package managers, like winget, choco, and brew. For more detials, you can follow the documentation: https://aka.ms/azure-dev/install.
After logging in with the following command, you will be able to use the azd cli to quickly provision and deploy the application.
```
azd login
```
Then, just use the `azd up` command to complete all operations of clone, provision and deployment.
Then, executes the commands `azd init` to initializes environment.
```
azd up -t dotnet-architecture/eShopOnWeb
azd init -t dotnet-architecture/eShopOnWeb
```
And executes the commands `azd up` to complete all operations of provision and deployment.
```
azd up
```
According to the prompt, enter an `env name`, and select `subscription` and `location`, these are the necessary parameters when you create resources. Wait a moment for the resource deployment to complete, click the web endpoint and you will see the home page.
**Notes:**
Considering security, we store its related data (id, password) in the key vault when we create the database, and obtain it from the key vault when we use it. This is different from directly deploying applications locally.
Considering security, we store its related data (id, password) in the **Azure Key Vault** when we create the database, and obtain it from the Key Vault when we use it. This is different from directly deploying applications locally.
You can also run the sample directly locally (See below).

View File

@@ -33,7 +33,7 @@ resource sqlServer 'Microsoft.Sql/servers@2022-05-01-preview' = {
resource firewall 'firewallRules' = {
name: 'Azure Services'
properties: {
// Allow all clients
// Allow all clients
// Note: range [0.0.0.0-0.0.0.0] means "allow all Azure-hosted clients only".
// This is not sufficient, because we also want to allow direct access from developer machine, for debugging purposes.
startIpAddress: '0.0.0.1'
@@ -127,4 +127,3 @@ resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = {
var connectionString = 'Server=${sqlServer.properties.fullyQualifiedDomainName}; Database=${sqlServer::database.name}; User=${appUser}'
output connectionStringKey string = connectionStringKey
output databaseName string = sqlServer::database.name
output connectionString string = connectionString

View File

@@ -32,6 +32,8 @@ param minimumElasticInstanceCount int = -1
param numberOfWorkers int = -1
param scmDoBuildDuringDeployment bool = false
param use32BitWorkerProcess bool = false
param ftpsState string = 'FtpsOnly'
param healthCheckPath string = ''
resource appService 'Microsoft.Web/sites@2022-03-01' = {
name: name
@@ -43,12 +45,14 @@ resource appService 'Microsoft.Web/sites@2022-03-01' = {
siteConfig: {
linuxFxVersion: linuxFxVersion
alwaysOn: alwaysOn
ftpsState: 'FtpsOnly'
ftpsState: ftpsState
minTlsVersion: '1.2'
appCommandLine: appCommandLine
numberOfWorkers: numberOfWorkers != -1 ? numberOfWorkers : null
minimumElasticInstanceCount: minimumElasticInstanceCount != -1 ? minimumElasticInstanceCount : null
use32BitWorkerProcess: use32BitWorkerProcess
functionAppScaleLimit: functionAppScaleLimit != -1 ? functionAppScaleLimit : null
healthCheckPath: healthCheckPath
cors: {
allowedOrigins: union([ 'https://portal.azure.com', 'https://ms.portal.azure.com' ], allowedOrigins)
}

View File

@@ -1,6 +1,6 @@
param name string = 'add'
param keyVaultName string = ''
param keyVaultName string
param permissions object = { secrets: [ 'get', 'list' ] }
param principalId string

View File

@@ -1,148 +0,0 @@
using Azure.Core;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text.Json;
using System.Text.RegularExpressions;
namespace Azure.Identity
{
public class AzureDeveloperCliCredential : TokenCredential
{
internal const string AzdCliNotInstalled = $"Azure Developer CLI could not be found. {Troubleshoot}";
internal const string AzdNotLogIn = "Please run 'azd login' from a command prompt to authenticate before using this credential.";
internal const string WinAzdCliError = "'azd is not recognized";
internal const string AzdCliTimeoutError = "Azure Developer CLI authentication timed out.";
internal const string AzdCliFailedError = "Azure Developer CLI authentication failed due to an unknown error.";
internal const string Troubleshoot = "Please visit https://aka.ms/azure-dev for installation instructions and then, once installed, authenticate to your Azure account using 'azd login'.";
internal const string InteractiveLoginRequired = "Azure Developer CLI could not login. Interactive login is required.";
private const string RefreshTokeExpired = "The provided authorization code or refresh token has expired due to inactivity. Send a new interactive authorization request for this user and resource.";
private static readonly string DefaultWorkingDirWindows = Environment.GetFolderPath(Environment.SpecialFolder.System);
private const string DefaultWorkingDirNonWindows = "/bin/";
private static readonly string DefaultWorkingDir = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? DefaultWorkingDirWindows : DefaultWorkingDirNonWindows;
private static readonly Regex AzdNotFoundPattern = new Regex("azd:(.*)not found");
public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken = default)
{
return RequestCliAccessTokenAsync(requestContext, cancellationToken)
.GetAwaiter()
.GetResult();
}
public override async ValueTask<AccessToken> GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken = default)
{
return await RequestCliAccessTokenAsync(requestContext, cancellationToken).ConfigureAwait(false);
}
private async ValueTask<AccessToken> RequestCliAccessTokenAsync(TokenRequestContext context, CancellationToken cancellationToken)
{
try
{
ProcessStartInfo processStartInfo = GetAzdCliProcessStartInfo(context.Scopes);
string output = await RunProcessAsync(processStartInfo);
return DeserializeOutput(output);
}
catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested)
{
throw new AuthenticationFailedException(AzdCliTimeoutError);
}
catch (InvalidOperationException exception)
{
bool isWinError = exception.Message.StartsWith(WinAzdCliError, StringComparison.CurrentCultureIgnoreCase);
bool isOtherOsError = AzdNotFoundPattern.IsMatch(exception.Message);
if (isWinError || isOtherOsError)
{
throw new CredentialUnavailableException(AzdCliNotInstalled);
}
bool isAADSTSError = exception.Message.Contains("AADSTS");
bool isLoginError = exception.Message.IndexOf("azd login", StringComparison.OrdinalIgnoreCase) != -1;
if (isLoginError && !isAADSTSError)
{
throw new CredentialUnavailableException(AzdNotLogIn);
}
bool isRefreshTokenFailedError = exception.Message.IndexOf(AzdCliFailedError, StringComparison.OrdinalIgnoreCase) != -1 &&
exception.Message.IndexOf(RefreshTokeExpired, StringComparison.OrdinalIgnoreCase) != -1 ||
exception.Message.IndexOf("CLIInternalError", StringComparison.OrdinalIgnoreCase) != -1;
if (isRefreshTokenFailedError)
{
throw new CredentialUnavailableException(InteractiveLoginRequired);
}
throw new AuthenticationFailedException($"{AzdCliFailedError} {Troubleshoot} {exception.Message}");
}
catch (Exception ex)
{
throw new CredentialUnavailableException($"{AzdCliFailedError} {Troubleshoot} {ex.Message}");
}
}
private async ValueTask<string> RunProcessAsync(ProcessStartInfo processStartInfo, CancellationToken cancellationToken = default)
{
var process = Process.Start(processStartInfo);
if (process == null)
{
throw new CredentialUnavailableException(AzdCliFailedError);
}
await process.WaitForExitAsync(cancellationToken);
if (process.ExitCode != 0)
{
var errorMessage = process.StandardError.ReadToEnd();
throw new InvalidOperationException(errorMessage);
}
return process.StandardOutput.ReadToEnd();
}
private ProcessStartInfo GetAzdCliProcessStartInfo(string[] scopes)
{
string scopeArgs = string.Join(" ", scopes.Select(scope => string.Format($"--scope {scope}")));
string command = $"azd auth token --output json {scopeArgs}";
string fileName;
string argument;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "cmd.exe");
argument = $"/c \"{command}\"";
}
else
{
fileName = "/bin/sh";
argument = $"-c \"{command}\"";
}
return new ProcessStartInfo
{
FileName = fileName,
Arguments = argument,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
ErrorDialog = false,
CreateNoWindow = true,
WorkingDirectory = DefaultWorkingDir,
};
}
private static AccessToken DeserializeOutput(string output)
{
using JsonDocument document = JsonDocument.Parse(output);
JsonElement root = document.RootElement;
string accessToken = root.GetProperty("token").GetString();
DateTimeOffset expiresOn = root.GetProperty("expiresOn").GetDateTimeOffset();
return new AccessToken(accessToken, expiresOn);
}
}
}