Azure MSI:用户登录失败''

时间:2018-04-02 09:16:52

标签: azure azure-resource-manager azure-msi

我正在尝试使用MSI令牌从App Service连接到数据库,并且正在

Login failed for user ''.

当我使用ARM部署App Service时,我生成了一个输出,确保它创建了一个服务主体:

 {
  "principalId":"98f2c1f2-0a86-4ff1-92db-d43ec0edxxxx","
  tenantId":"e6d2d4cc-b762-486e-8894-4f5f440dxxxx",
  "type":"SystemAssigned"
 }

我还检查了Kudu的环境变量,并且:

MSI_ENDPOINT = http://127.0.0.1:41239/MSI/token/
MSI_SECRET = 7C1B16Fxxxxxxxxxxxxx

我在Azure门户中提供了一个连接字符串,如下所示:

Data Source=nzmoebase0001bt.database.windows.net;Initial Catalog=nzmoebase0001bt;Connect Timeout=300;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;
  

作为一个越位,MSI(理论上)允许人们从源代码剪切/粘贴到公共论坛而不必担心留下秘密?只是说着......现在......如果我能让它发挥作用!!!

我已将主体作为所有者添加到数据库中......

但我还是得到了:

Login failed for user ''.

我还应该尝试什么?

谢谢。

@juunas:使用以下方式添加令牌:

    static async Task AttachAccessTokenToDbConnection(IDbConnection dbConnection)
    {
        SqlConnection sqlConnection = dbConnection as SqlConnection;
        if (sqlConnection == null)
        {
            return;
        }
        string msiEndpoint = Environment.GetEnvironmentVariable("MSI_ENDPOINT");
        if (string.IsNullOrEmpty(msiEndpoint))
        {
            return;
        }

        var msiSecret = Environment.GetEnvironmentVariable("MSI_SECRET");
        if (string.IsNullOrEmpty(msiSecret))
        {
            return;
        }

        // To get around:
        // "Cannot set the AccessToken property if 'UserID', 'UID', 'Password', or 'PWD' has been specified in connection string."
        var terms = new[] {"UserID","Password","PWD=","UID=" };
        string connectionString = dbConnection.ConnectionString;

        foreach (var term in terms)
        {
            if (connectionString.Contains(term, StringComparison.InvariantCultureIgnoreCase))
            {
                return;
            }
        }

        string accessToken = await AppCoreDbContextMSITokenFactory.GetAzureSqlResourceTokenAsync();
        sqlConnection.AccessToken = accessToken;
    }

更新: 从实体框架

获得一些进展(不完全确定改变了什么)
This operation requires a connection to the 'master' database. Unable to create a connection to the 'master' database because the original database connection has been opened and credentials have been removed from the connection string. Supply an unopened connection.

我根据网上的一些建议添加了Persist Security Info = True,但没有太大变化。

Data Source=nzmoebase0001bt.database.windows.net;Initial Catalog=nzmoebase0001bt;MultipleActiveResultSets=False;Persist Security Info = True;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;

根据@evilSnobu,我最终得到了跟踪并捕获了令牌:

 .eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI....

使用jwt.io解码的是:

{
  "typ": "JWT",
  "alg": "RS256",
  "x5t": "FSimuFrFNoC0sJXGmv13nNZceDc",
  "kid": "FSimuFrFNoC0sJXGmv13nNZceDc"
}.{
  "aud": "https://database.windows.net/",
  "iss": "https://sts.windows.net/e6d2d4cc-b762-486e-8894-4f5f440dxxxx/",
  "iat": 1522783025,
  "nbf": 1522783025,
  "exp": 1522786925,
  "aio": "Y2NgYPjNdyJd9zrzpLavJSEzNIuPAAA=",
  "appid": "d1057cea-461b-4946-89a9-d76439c2xxxx",
  "appidacr": "2",
  "e_exp": 262800,
  "idp": "https://sts.windows.net/e6d2d4cc-b762-486e-8894-4f5f440dxxxx/",
  "oid": "98f2c1f2-0a86-4ff1-92db-d43ec0edxxxx",
  "sub": "98f2c1f2-0a86-4ff1-92db-d43ec0edxxxx",
  "tid": "e6d2d4cc-b762-486e-8894-4f5f440dxxxx",
  "uti": "59bqKWiSL0Gf0bTCI0AAAA",
  "ver": "1.0"
}.[Signature]

对于我未经训练的眼睛看起来很棒(?)。但我仍然得到:

System.Data.SqlClient.SqlException: Login failed for user ''.

这似乎是来自更深层次的消息与EntityFramework的启动模式检查过程的关系:

[InvalidOperationException: This operation requires a connection to the 'master' database. Unable to create a connection to the 'master' database because the original database connection has been opened and credentials have been removed from the connection string. Supply an unopened connection.]

任何和所有建议都非常感谢。谢谢!

1 个答案:

答案 0 :(得分:1)

我现在按照此文档追寻“此操作需要连接到'master'数据库的错误”错误: https://docs.microsoft.com/en-us/azure/app-service/app-service-web-tutorial-connect-msi

我认为在分配令牌后包含以下行是关键:

selector

就我而言,我们有一些代码明确运行实体框架迁移,从而导致错误。当我们禁用它时,该应用程序开始按预期运行。