如何将Azure应用程序appRoles(在应用程序清单中定义)用作Azure SQL中的角色

时间:2017-03-07 19:23:14

标签: azure-sql-database azure-active-directory role-base-authorization azure-sql-server

我们的团队希望在Azure门户中注册应用程序时使用应用程序清单中定义的应用程序角色。以下是TestApp清单中的示例。

  "appRoles": [
  { "allowedMemberTypes": [
      "User",
      "Application"],
    "displayName": "My App Role 2",
    "id": "0993b354-6b2f-471d-bba2-f7467a1bbbf2",
    "isEnabled": true,
    "description": "My App Role description for MyAppRole2",
    "value": "MyAppRole2" },
  { "allowedMemberTypes": [
      "User" ],
    "displayName": "My App Role 1",
    "id": "0993b354-6b2f-471d-bba2-f7467a1baaf2",
    "isEnabled": true,
    "description": "My App Role description for MyAppRole1",
    "value": "MyAppRole1" }]

这些应用程序角色在Web应用程序中显示为角色声明,允许开发人员通过修改端点来控制对端点的访问,如下所示。

[Authorize (Roles = "MyAppRole2")]
public class AdministrationController : Controller
{
}

通过Azure门户(在企业应用程序下),我们可以将用户和/或组分配给特定应用程序的角色,一切运行良好。但是,在尝试直接访问数据库时(从SSMS),应用程序角色的成员身份不起作用。

CREATE USER [TestApp] FROM EXTERNAL PROVIDER
CREATE ROLE [MyAppRole2] AUTHORIZATION [TestApp1]

我们也试过

CREATE ROLE [My App Role 2] AUTHORIZATION [TestApp1]

在任何一种情况下,检查数据库级别的成员资格都会返回“0”false。

SELECT IS_MEMBER('MyAppRole2') [My App Role 2]

但是,如果我们创建一个AAD组(例如,我的TestApp我的应用程序角色2组),请通过企业应用程序界面将“我的应用程序角色2”角色分配给该组,并将用户分配给该组通过AAD用户和组界面...我们可以通过在SQL中使用组来查看到组的成员资格。

以下内容在AAD中创建Azure SQL与组安全主体之间的关系。

CREATE USER [My Group For TestApp My App Role 2] FROM EXTERNAL PROVIDER

任何直接登录到该组中的SQL的用户都将显示为该组的成员。对于同时也是AAD组成员的经过身份验证的SSMS用户,以下内容返回true。

SELECT IS_MEMBER('My Group For TestApp My App Role 2')

虽然这有效,但如果我们从组中删除应用程序角色(在Azure企业应用程序下),则上述查询仍会返回true。这是因为即使该组不再具有对应用程序角色的访问权限,该用户仍然是该组的有效成员。因此,此解决方法无效,因为数据库实际上并未验证用户是否参与了应用程序角色。

我们如何直接将应用程序角色与数据库角色相关联以确保适当的安全性?

1 个答案:

答案 0 :(得分:0)

根据我的理解,您将Azure AD应用程序中定义的应用程序角色与Application Roles in SQL Server混合。

如果要使用角色管理Azure AD服务主体。我们可以使用以下命令创建数据库角色,并将角色分配给Azure AD中的服务主体创建:

CREATE ROLE customRole2

alter role customRole2 add member FeiTestApp
--FeiTestApp is the service principal in Azure AD
EXECUTE AS USER = 'FeiTestApp';  

SELECT IS_MEMBER('customRole2')
REVERT;

该命令应该返回1,然后我们也可以使用访问令牌来检查结果,如下所示:

SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
builder["Data Source"] = "xxxx.database.windows.net"; // replace with your server name
builder["Initial Catalog"] = "DBTest"; // replace with your database name
builder["Connect Timeout"] = 30;

string authority = "https://login.microsoftonline.com/{0}";
string tenantId = "microsoft.onmicrosoft.com";
string clientId = "";
string secrect = "";
string resourceId = "https://database.windows.net/";
AuthenticationContext authContext = new AuthenticationContext(string.Format(authority,tenantId));
var accessToken=  authContext.AcquireTokenAsync(resourceId, new ClientCredential(clientId, secrect)).Result.AccessToken;

using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
{
    try
    {
        connection.AccessToken = accessToken;
        connection.Open();         
        SqlCommand cmd = new SqlCommand("SELECT IS_MEMBER('customRole2')", connection);

        var reader = cmd.ExecuteReader();
        while (reader.Read())
        {
            Console.WriteLine($"{reader[0]}");              
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

有关Azure SQL数据库角色管理的更多详细信息,您可以参考以下文档:

Principals (Database Engine)