【问题标题】:How to use Azure AD for authentication for multiple instances of same application如何使用 Azure AD 对同一应用程序的多个实例进行身份验证
【发布时间】:2019-12-27 16:23:36
【问题描述】:

我是 Azure Active Directory 身份验证的新手,我正在尝试弄清楚如何实现我们对 Azure Active Directory 身份验证的要求。

我们有同一个 Web 应用程序的多个实例。即每个客户端有一个虚拟目录和一个数据库。不应允许来自一个实例的用户访问应用程序的其他实例。我们是否可以使用包含所有用户的单个 Active Directory 和单个 Azure AD 应用程序来实现这一点,或者我们是否需要为每个客户端创建 Active Directory 和单独的 Azure AD 应用程序?限制将通过应用程序代码实现,但是有没有办法对用户进行分组,以便我们可以在身份验证响应中获取一些值来确定用户可以访问哪个实例?

【问题讨论】:

标签: c# azure azure-active-directory


【解决方案1】:

1.我们有同一个 Web 应用程序的多个实例。即每个客户端有一个虚拟目录和一个数据库。用户来自 一个实例不应被允许访问其他实例 应用。我们可以使用单个 Active Directory 来实现这一点吗? 里面的所有用户?

是的,你可以这样做。 您可以为 Azure SQL Server 中的每个数据库创建 Azure AD 组,并将 SQL 角色分配给该组。那么如果你想让一个用户访问一个数据库,你只需要将该用户添加到组中。更多详情请参考document 步骤如下

  1. 为 Azure SQL 服务器创建 Azure AD 管理员
Connect-AzAccount
Set-AzSqlServerActiveDirectoryAdministrator -ResourceGroupName "Group-23" -ServerName "demo_server" -DisplayName "user name" -ObjectId "user object id"
  1. Create Azure AD group for each database

    一个。使用上面的 Azure AD 使用登录 SQL 服务器 vai SSMS 湾。创建

    CREATE USER [GroupNmae] FROM EXTERNAL PROVIDER
    ALTER ROLE db_owner ADD MEMBER [GroupNmae]
    
  2. 将用户添加到 AD 组
Connect-AzureAD
Add-AzureADGroupMember -ObjectId <group id> -RefObjectId <user id>

2.限制将通过应用程序代码实现,但是有没有办法对用户进行分组,以便我们可以在其中获得一些价值 身份验证响应以识别用户可以使用哪个实例 访问权限?

根据我的测试,我们可以使用 AzureAD 令牌角色声明来实现。我们可以通过为 AD 组分配应用角色来为 Azure SQL 服务器中的每个数据库创建应用角色。更多应用角色详情请参考document

详细步骤如下。

  1. Create Azure AD application

  2. 配置应用权限

  3. 添加应用角色

    • 选择您要在其中定义应用角色的应用。然后选择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,
  1. 代码

    一个。创建 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);
     }
    

    b.获取角色值

     ClaimsPrincipal.Current.FindFirst("roles").Value;
    

关于如何实现,可以参考sample了解更多详情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-10
    • 1970-01-01
    • 2019-05-29
    • 2017-10-30
    • 1970-01-01
    • 2019-04-12
    • 1970-01-01
    相关资源
    最近更新 更多