簡體   English   中英

無法從 Web 服務在數據庫中創建用戶和更新用戶

[英]Not able to create user and update user in Database from web service

這可能是重復的問題,但我無法找到解決方案。 我有一個用 C# 和 .net core 編碼的 web 服務,我試圖通過它在數據庫中創建一個用戶(SQL Server Management Studio)。 當我嘗試通過 SSMS 創建用戶時,查詢工作正常,但它無法通過該功能工作。 下面是函數:

     public async Task CreateUserNameQuery(string username, string password)
        { 

object[] sqlParams = {new SqlParameter("@username", username),  new SqlParameter("@password", password)};
           
            
            string query3 = "IF USER_ID ('{@username}') IS NULL " + "\n" +
                            "CREATE USER {@username} WITH PASSWORD=N'{@password}', DEFAULT_SCHEMA=[dbo] " + "\n" +
                            "ELSE " + "\n" +
                            "ALTER USER {{@username}} WITH PASSWORD=N'{{@password}}', DEFAULT_SCHEMA=[dbo] " + "\n" +
                            "GO " + "\n" +
                            "sys.sp_addrolemember @rolename = N'db_datareader', @membername = N'{{@username}}' " + "\n" +
                            "GO ";

           var result = await Database.ExecuteSqlRawAsync(query3, sqlParams);
            
          
            Database.SetCommandTimeout(600);
        }

以下是我得到的異常:

Input string was not in a correct format.


    at System.Text.StringBuilder.FormatError()
   at System.Text.StringBuilder.AppendFormatHelper(IFormatProvider provider, String format, ParamsArray args)
   at System.String.FormatHelper(IFormatProvider provider, String format, ParamsArray args)
   at System.String.Format(String format, Object[] args)
   at Microsoft.EntityFrameworkCore.Storage.Internal.RawSqlCommandBuilder.Build(String sql, IEnumerable`1 parameters)
   at Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.ExecuteSqlRawAsync(DatabaseFacade databaseFacade, String sql, IEnumerable`1 parameters, CancellationToken cancellationToken)
  

我們去掉用戶名中任何非 az 的東西怎么樣? 結果是很難注入任何東西。 這確實引入了用戶名必須是 ascii az 的規則,但是真的有人需要'DROP TABLE Students;--的用戶名嗎? (如果他們真的這樣做,見底部)

        public async Task CreateUserNameQuery(string username, string password)
        { 
            username = Regex.Replace(username, "[^a-z]", "");
           
            string query3 = $@"
IF DATABASE_PRINCIPAL_ID('{username}') IS NULL
    CREATE USER {username} WITH PASSWORD={{0}}, DEFAULT_SCHEMA=[dbo] 
ELSE
    ALTER USER {username} WITH PASSWORD={{0}}, DEFAULT_SCHEMA=[dbo]";

            await Database.ExecuteSqlRawAsync(query3, username, password);

            await Database.ExecuteSqlInterpolatedAsync("EXECUTE sys.sp_addrolemember @rolename = N'db_datareader', @membername = {username}");
        }

我相當確定您可以參數化密碼,因為它通常以字符串常量的形式呈現 - 它只是作為標識符呈現的用戶名 - 但我無法測試它。 如果它不起作用讓我知道

最后說明; 你不能將 GO 發送到 SQLS 服務器; SSMS 使用 GO 作為分隔符來分解腳本,您也應該這樣做(這里我做了兩個查詢來模擬 GO 的任一側)


如果你真的需要你的用戶名包含各種古怪的東西,也許最簡單的方法是讓數據庫為你引用它,然后在字符串中使用引用的值。 在域模型中選擇任何合適的具有字符串屬性的對象,例如 Order 並執行將用戶名引用到字符串屬性中的原始查詢(讓我們想象一下 orderreference)

var x = (await context.Order.AsNoTracking().FromSqlInterpolated($"SELECT -1 as OrderId, QUOTENAME({username}) as OrderReference").FirstAsync()).OrderReference;

x現在將包含,對於abc[]def的輸入, [abc[]]def]可以安全地連接到無法參數化的位置的 sql

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM