c# - 如何使用 Azure AD 对同一应用程序的多个实例进行身份验证
问题描述
我是 Azure Active Directory 身份验证的新手,我正在尝试弄清楚如何实现我们对 Azure Active Directory 身份验证的要求。
我们有同一个 Web 应用程序的多个实例。即每个客户端有一个虚拟目录和一个数据库。不应允许来自一个实例的用户访问应用程序的其他实例。我们是否可以使用包含所有用户的单个 Active Directory 和单个 Azure AD 应用程序来实现这一点,或者我们是否需要为每个客户端创建 Active Directory 和单独的 Azure AD 应用程序?限制将通过应用程序代码实现,但是有没有办法对用户进行分组,以便我们可以在身份验证响应中获得一些值来确定用户可以访问哪个实例?
解决方案
1. 我们有同一个 Web 应用程序的多个实例。即每个客户端有一个虚拟目录和一个数据库。不应允许来自一个实例的用户访问应用程序的其他实例。我们可以使用包含所有用户的单个 Active Directory 来实现这一点吗?
是的,你可以这么做。您可以为 Azure SQL Server 中的每个数据库创建 Azure AD 组,并将 SQL 角色分配给该组。那么如果你想让一个用户访问一个数据库,你只需要将用户添加到组中。更多详细信息,请参阅文档 步骤如下
- 为 Azure SQL 服务器创建 Azure AD 管理员
Connect-AzAccount
Set-AzSqlServerActiveDirectoryAdministrator -ResourceGroupName "Group-23" -ServerName "demo_server" -DisplayName "user name" -ObjectId "user object id"
-
一个。使用上面的 Azure AD 使用登录 SQL 服务器 vai SSMS b。创造
CREATE USER [GroupNmae] FROM EXTERNAL PROVIDER ALTER ROLE db_owner ADD MEMBER [GroupNmae]
- 将用户添加到 AD 组
Connect-AzureAD
Add-AzureADGroupMember -ObjectId <group id> -RefObjectId <user id>
2.限制将通过应用程序代码实现,但是有没有办法对用户进行分组,以便我们可以在身份验证响应中获取一些值来识别用户可以访问哪个实例?
根据我的测试,我们可以使用 AzureAD 令牌角色声明来实现。我们可以通过为 AD 组分配应用角色来为 Azure SQL 服务器中的每个数据库创建应用角色。更多关于应用角色的信息,请参考文档
详细步骤如下。
添加应用角色
选择您要在其中定义应用程序角色的应用程序。然后选择
Manifest
。appRoles
通过找到设置并添加所有应用程序角色来编辑应用程序清单
例如
"appId": "8763f1c4-f988-489c-a51e-158e9ef97d6a",
"appRoles": [
{
"allowedMemberTypes": [
"User"
],
"displayName": "your databse name",
"id": "<GUID>",
"isEnabled": true,
"description": "access database <your databse name>",
"value": "your databse name"
}
],
"availableToOtherTenants": false,
代码
一个。创建 Stratup.cs
public void ConfigureAuth(IAppBuilder app) { JwtSecurityTokenHandler.DefaultMapInboundClaims = false; app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); app.UseCookieAuthentication(new CookieAuthenticationOptions()); app.UseOpenIdConnectAuthentication( new OpenIdConnectAuthenticationOptions { Authority = authority, ClientId = appId, ClientSecret = appSecret, RedirectUri = redirectUri, PostLogoutRedirectUri = redirectUri, Scope = "openid profile offline_access https://database.windows.net//.default", ResponseType=OpenIdConnectResponseTypes.CodeIdToken, TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false, RoleClaimType = "roles" }, Notifications = new OpenIdConnectAuthenticationNotifications() { AuthenticationFailed = OnAuthenticationFailed, AuthorizationCodeReceived= OnAuthorizationCodeReceived } } ); } private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedNotification notification) { var idClient = var idClient = ConfidentialClientApplicationBuilder.Create(appId) .WithAuthority(authority) .WithRedirectUri(redirectUri) .WithClientSecret(appSecret) .Build(); string[] scopes = "openid profile offline_access https://database.windows.net//.default".Split(' '); AuthenticationResult result = await idClient.AcquireTokenByAuthorizationCode(scopes, notification.Code).ExecuteAsync(); } private Task OnAuthenticationFailed(AuthenticationFailedNotification<Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification) { notification.HandleResponse(); notification.Response.Redirect("/Error?message=" + notification.Exception.Message); return Task.FromResult(0); }
湾。获取角色值
ClaimsPrincipal.Current.FindFirst("roles").Value;
关于如何实现这一点,您可以参考示例以获取更多详细信息。
推荐阅读
- android - 使用 inter-op 时,jetpack compose 中的惰性列表相互堆叠
- php - 将Mysql中的2000万条数据分批。请建议一种更快的方法?
- google-colaboratory - 如何在 Google Colab 中拆分文件夹并将其保存到 Google Drive?
- python - /profile/ 'function' 对象的 AttributeError 没有属性 'object
- javascript - 如何多次使用 fetch() 的结果而不使其变得未定义?(JS新手)
- python - 用于存储相同整数的变量在单行和多行中是不同的
- sql - SQL 中的下一个正数日期
- pine-script - 获取每次交易后的利润百分比变化
- reactjs - useEffect Hook 依赖和 useState hook
- javascript - 将 unicode 转换为 html