2013-02-13 44 views
4

我試圖更新使用ALTER LOGIN爲現有的SQL登錄密碼如何更改與變量SQL登錄密碼

我知道了以下工作

ALTER LOGIN [username1] WITH PASSWORD = 'somenewpassword123'; 

然而,當我嘗試使用局部變量

DECLARE @newpass nvarchar(max); 
SET @newpass = '[email protected]'; 
ALTER LOGIN [username1] WITH PASSWORD = @newpass; 

失敗。在變量中添加[]大括號似乎在SSMS查詢編輯器中解決了這個問題,但是通過在C#中編寫查詢來編程式地使用它,它失敗了,因爲上面的語句具有相同的錯誤(PASSWORD處的語法錯誤)

c#應用

public static int UpdateSqlLoginPassword(DbContext context, string loginName, string password) 
{ 
try 
{ 
    string updatePassword = 
     @" SET NOCOUNT ON 
      DECLARE @loginName AS nvarchar(max) = {0} 
      DECLARE @password AS nvarchar(max) = {1} 
      EXEC(' 
      USE master 
      ALTER LOGIN ['+ @loginName + '] WITH PASSWORD = ['+ @password + '] 
      ')"; 
    return context.Database.ExecuteSqlCommand(updatePassword, loginName, password); 
} 
catch (Exception) 
{ 
    return -2; 
} 
} 

我也試圖散列密碼(認爲與該變量的問題),但這裏的語法不被接受

DECLARE @newpass nvarchar(max); 
SET @newpass = '[email protected]'; 
DECLARE @hashedpass varbinary(max); 
SET @hashedpass = HASHBYTES('SHA1', CONVERT(nvarchar(max),@newpass)); 

ALTER LOGIN [newuser10] WITH PASSWORD = @hashedpass HASHED; 
SELECT @hashedpass; 

誰能幫助我瞭解如何更新在s中登錄密碼ql使用變量而不是固定值?

在此先感謝

更新

基於從查理建議我也試過以下

public static int UpdateSqlLoginPassword(DbContext context, string loginName, string password) 
     { 
      try 
      { 
       string updatePassword = 
        @"ALTER LOGIN [' + @loginName +'] WITH PASSWORD = @password "; 
       return context.Database.ExecuteSqlCommand(updatePassword, new SqlParameter("loginName", loginName), new SqlParameter("password", password)); 
      } 
      catch (Exception) 
      { 
       return -2; 
      } 
     } 

這仍然產生不正確的SQLException新的語法「@密碼」。 如果我振奮參數

public static int UpdateSqlLoginPassword(DbContext context, string loginName, string password) 
     { 
      try 
      { 
       string updatePassword = 
        @"ALTER LOGIN [' + @loginName +'] WITH PASSWORD = [' + @password +']"; 
       return context.Database.ExecuteSqlCommand(updatePassword, new SqlParameter("loginName", loginName), new SqlParameter("password", password)); 
      } 
      catch (Exception) 
      { 
       return -2; 
      } 
     } 

我那麼近生成密碼SQLEXCEPTION不正確的語法。

UPDATE2

使用從查理更新的建議,我嘗試雖然看起來查詢字符串正確地形成了以下則拋出SQLException *名稱使用QUOTENAME函數

 string sql = @"DECLARE @sql NVARCHAR(500) 
       SET @sql = 'ALTER LOGIN ' + QuoteName(@loginName) + 
       ' WITH PASSWORD = ' + QuoteName(@password, '''') 
       EXEC @sql"; 
     return context.Database.ExecuteSqlCommand(sql, new SqlParameter("loginName", loginName), new SqlParameter("password", password)); 

'ALTER LOGIN [newuser10] WITH PASSWORD ='t#P @ ssw0rd''不是有效的標識符。

編輯

一些是由一個語法錯誤包裹@sql產生的錯誤更多的閱讀後,查詢的,沒有錯誤

string sql = @"DECLARE @sql NVARCHAR(500) 
        SET @sql = 'ALTER LOGIN ' + QuoteName(@loginName) + 
        ' WITH PASSWORD = ' + QuoteName(@password, '''') 
        EXEC(@sql)"; 

在一個側面說明執行:通過簡單地建立該字符串並運行它作爲

string updatePassword = "USE MASTER ALTER LOGIN [" + loginName + "] WITH PASSWORD = '" + password + "'"; 
return context.Database.ExecuteSqlCommand(updatePassword); 

以上也是一種解決方法並更新sql登錄。儘管此代碼的實現最大限度地減少了sql注入的可能性,但這並不是最理想的方法。

-Thanks

+1

究竟它是如何失敗的?你是否收到錯誤信息? – 2013-02-13 16:24:04

+0

如果你只是用PASSWORD = @newpass運行ALTER LOGIN [用戶名]在c#中運行上面的代碼塊會捕獲相同的異常,因爲它正在從sql查詢中冒泡 – rlcrews 2013-02-13 16:27:31

回答

6

您需要在DbContext級別使用的參數。詳情請參閱this answer,但是,這裏有一個代碼示例(改編自同一頁):

string sql = "ALTER LOGIN @loginName WITH PASSWORD = @password"; 
ctx.Database.ExecuteSqlCommand(
    sql, 
    new SqlParameter("loginName", loginName), 
    new SqlParameter("password", password)); 

這裏(到處)使用參數的目的是爲了防止SQL注入攻擊。考慮到您正在編寫更改密碼的代碼,這一點尤其重要。

UPDATE

的ALTER LOGIN語句不會使用變量;它必須通過動態SQL完成。以下是更新代碼示例:

string sql = @"DECLARE @sql NVARCHAR(500) 
       SET @sql = 'ALTER LOGIN ' + QuoteName(@loginName) + 
        ' WITH PASSWORD= ' + QuoteName(@password, '''') 
       EXEC @sql "; 
ctx.Database.ExecuteSqlCommand(
    sql, 
    new SqlParameter("loginName", loginName), 
    new SqlParameter("password", password)); 

請注意,我們仍在使用SqlParameters來防止SQL注入攻擊。我們還使用T-SQL方法QuoteName在我們正在生成的SQL中進行適當的引用;但這種方法只需將字符(在第一個調用中)或'個字符(在第二個中)任何[字符加倍。對於SQL注入攻擊還有很多其他向量,所以僅僅依靠QuoteName是不夠的。

+1

sp_password被注意爲在將來的SQL Server版本中被刪除,並且它們指向您使用ALTER LOGIN http://msdn.microsoft.com/en-us/library/ms174428.aspx。我只知道因爲我先去了那裏;) – 2013-02-13 16:29:16

+0

哈!我沒有意識到,我會相應地更新我的答案。 – 2013-02-13 16:29:50

+1

感謝查理我會給這個嘗試我是避免基於它將被棄用的sp_password。我知道這將是一個出路,但我是按照MSDN的建議 – rlcrews 2013-02-13 16:30:24

0

我對Azure SQL使用上述答案,直到我將「EXEC @sql」替換爲「EXEC(@sql)」時,我纔得到「無效標識符」錯誤。見Msg 203, Level 16, State 2, is not a valid identifier

此外,我不得不使用 「ALTER USER」,而不是 「ALTER LOGIN」