如何使用 Pulumi 向 Web App 添加身份验证
Posted
技术标签:
【中文标题】如何使用 Pulumi 向 Web App 添加身份验证【英文标题】:How to add Authentiction to WebApp with Pulumi 【发布时间】:2022-01-19 18:13:14 【问题描述】:我正在尝试向 Pulumi WebApp 添加身份验证提供程序,但我完全不清楚如何实现这一点。来自包@pulumi/azure-native/web
的类WebApp
仅提供属性identity
,但没有分配属性,例如微软广告。任何人都可以提供有关如何设置的提示吗?
【问题讨论】:
【参考方案1】:有一些Pulumi Azure pre-requisites 并且在你的租户和 Azure 订阅中具有适当的权限。
按照以下步骤使用 pulumi 将身份验证添加到应用服务 webapp 并部署:
创建项目:
首先创建应用程序,然后添加创建 Azure AD application registration 所需的 AzureAD 包。
pulumi new azure-csharp `
--name easyauth-webapp `
--description "azure ad secured app" `
--stack dev `
--config azure-native:location=eastus
dotnet add package Pulumi.AzureAD
接下来我们需要更新pulumi.dev.yaml
文件的内容以包含一些额外的配置项。将以下内容粘贴到文件中:
config:
azure-native:location: eastus
azure-native:subscriptionId: UPDATE_ME
azure-native:tenantId: UPDATE_ME
easyauth-webapp:tenantId: UPDATE_ME
easyauth-webapp:ownerId: UPDATE_ME
easyauth-webapp:siteName: UPDATE_ME
easyauth-webapp:appRegistrationName: UPDATE_ME
您可以将siteName
和appRegistrationName
设置为您想要的任何值。
subscriptionId
和 tenantId
应分别设置为 Azure 应用服务和 Azure AD 应用注册的相应目标。
以下命令可能有助于检索这些值:
# Get your user's id
az ad signed-in-user show --query objectId
# List all subscriptions (and their tenant) that you have access to
az account list
部署网站(没有安全措施):
接下来我们将创建要部署的网站。我们将使用run from ZIP package 功能来部署wwwroot
文件夹的内容。
创建该文件夹并向index.htm
文件添加一些内容:
例如:
<!-- wwwroot/index.htm -->
<html>
<head>
<title>A very secure app</title>
</head>
<body>
Hello EasyAuth with Pulumi!
</body>
</html>
现在我们可以使用 Pulumi 将此文件部署到 Azure。
修改MyStack.cs
文件以包含以下代码,该代码已改编自Pulumi Function Stack example:
// MyStack.cs
using System;
using Pulumi;
using Pulumi.AzureAD;
using Pulumi.AzureAD.Inputs;
using Pulumi.AzureNative.Resources;
using Pulumi.AzureNative.Storage;
using Pulumi.AzureNative.Storage.Inputs;
using Pulumi.AzureNative.Web;
using Pulumi.AzureNative.Web.Inputs;
class MyStack : Stack
public MyStack()
var config = new Pulumi.Config();
var tenantId = config.Require("tenantId");
var ownerId = config.Require("ownerId");
var siteName = config.Require("siteName");
var appRegistrationName = config.Require("appRegistrationName");
var rg = new ResourceGroup($"RG-siteName");
var storageAccount = new StorageAccount("storageaccount", new StorageAccountArgs
ResourceGroupName = rg.Name,
Kind = "StorageV2",
Sku = new SkuArgs
Name = SkuName.Standard_LRS,
,
);
var appServicePlan = new AppServicePlan("appserviceplan", new AppServicePlanArgs
ResourceGroupName = rg.Name,
Kind = "App",
Sku = new SkuDescriptionArgs
Tier = "Basic",
Name = "B1",
,
);
var container = new BlobContainer("zips", new BlobContainerArgs
AccountName = storageAccount.Name,
PublicAccess = PublicAccess.None,
ResourceGroupName = rg.Name,
);
var blob = new Blob("appservice-blob", new BlobArgs
ResourceGroupName = rg.Name,
AccountName = storageAccount.Name,
ContainerName = container.Name,
Type = BlobType.Block,
Source = new FileArchive("wwwroot"),
);
var codeBlobUrl = SignedBlobReadUrl(blob, container, storageAccount, rg);
var app = new WebApp("app", new WebAppArgs
Name = siteName,
ResourceGroupName = rg.Name,
ServerFarmId = appServicePlan.Id,
SiteConfig = new SiteConfigArgs
AppSettings =
new NameValuePairArgs
Name = "WEBSITE_RUN_FROM_PACKAGE",
Value = codeBlobUrl,
,
);
this.Endpoint = app.DefaultHostName;
// From https://github.com/pulumi/examples/blob/master/azure-cs-functions/FunctionsStack.cs
private static Output<string> SignedBlobReadUrl(Blob blob, BlobContainer container, StorageAccount account, ResourceGroup resourceGroup)
return Output.Tuple<string, string, string, string>(
blob.Name, container.Name, account.Name, resourceGroup.Name).Apply(t =>
(string blobName, string containerName, string accountName, string resourceGroupName) = t;
var blobSAS = ListStorageAccountServiceSAS.InvokeAsync(new ListStorageAccountServiceSASArgs
AccountName = accountName,
Protocols = HttpProtocol.Https,
SharedAccessStartTime = "2021-01-01",
SharedAccessExpiryTime = "2030-01-01",
Resource = SignedResource.C,
ResourceGroupName = resourceGroupName,
Permissions = Permissions.R,
CanonicalizedResource = "/blob/" + accountName + "/" + containerName,
ContentType = "application/json",
CacheControl = "max-age=5",
ContentDisposition = "inline",
ContentEncoding = "deflate",
);
return Output.Format($"https://accountName.blob.core.windows.net/containerName/blobName?blobSAS.Result.ServiceSasToken");
);
[Output] public Output<string> Endpoint get; set;
我们现在可以部署站点并验证它是否按预期工作:
pulumi up --stack dev
curl (pulumi stack --stack dev output Endpoint)
[
保护网站:
要配置 Easy Auth,我们首先创建一个 Azure AD 应用程序注册。
在此示例中,我指定了 AzureADMyOrg
,它限制了对部署应用程序注册的租户的访问。我还添加了一个 RedirectUri
,它指向已部署站点的 Easy Auth 中间件。需要密码才能用作客户端机密(在这种情况下,Web 应用程序是客户端)。
创建应用程序注册后,我们可以将WebAppAuthSettings 添加到我们的网站。该示例指定无匿名访问(使用RedirectToLoginPage
),并使用ClientId
和ClientSecret
(密码)将站点连接到应用程序注册。
将下面的代码粘贴到上面MyStack.cs
中的this.Endpoint...
代码之后:
// MyStack.cs
// After this.Endpoint = app.DefaultHostName;
var adApp = new Application("ADAppRegistration", new ApplicationArgs
DisplayName = appRegistrationName,
SignInAudience = "AzureADMyOrg",
Owners = new[] ownerId ,
Web = new ApplicationWebArgs
ImplicitGrant = new ApplicationWebImplicitGrantArgs
IdTokenIssuanceEnabled = true
,
RedirectUris = new System.Collections.Generic.List<string> $"https://siteName.azurewebsites.net/.auth/login/aad/callback"
);
var applicationPassword = new ApplicationPassword("appPassword", new ApplicationPasswordArgs
ApplicationObjectId = adApp.Id,
DisplayName = "Client secret for web app"
);
var allowedAudience = adApp.ApplicationId.Apply(id => $"api://id");
var authSettings = new WebAppAuthSettings("authSettings", new WebAppAuthSettingsArgs
ResourceGroupName = rg.Name,
Name = app.Name,
Enabled = true,
UnauthenticatedClientAction = UnauthenticatedClientAction.RedirectToLoginPage,
DefaultProvider = BuiltInAuthenticationProvider.AzureActiveDirectory,
ClientId = adApp.ApplicationId,
ClientSecret = applicationPassword.Value,
Issuer = $"https://sts.windows.net/tenantId/v2.0",
AllowedAudiences = new[] allowedAudience ,
);
我们现在可以更新站点了,从命令行我们无法比这更进一步。 但在浏览器中,我们将被重定向以完成登录流程并访问该站点。
pulumi up --stack dev
# Redirect to HTTPS
curl (pulumi stack --stack dev output Endpoint)
# Access denied
curl "https://$(pulumi stack --stack dev output Endpoint)"
请参阅此Github 链接以获取 pulumi 样本。
【讨论】:
以上是关于如何使用 Pulumi 向 Web App 添加身份验证的主要内容,如果未能解决你的问题,请参考以下文章
使用 Pulumi 创建 EKS 后如何修改 `aws-auth` Config Map?
如何将 Pulumi Azure 资源迁移到 Azure-Nextgen?