Alter LOGIN を使用して、既存の SQL ログインのパスワードを更新しようとしています。
以下の作品を知っている
ALTER LOGIN [username1] WITH PASSWORD = 'somenewpassword123';
ただし、ローカル変数を使用しようとすると
DECLARE @newpass nvarchar(max);
SET @newpass = 'P@ssw0rd12345';
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 = 'P@ssw0rd12345';
DECLARE @hashedpass varbinary(max);
SET @hashedpass = HASHBYTES('SHA1', CONVERT(nvarchar(max),@newpass));
ALTER LOGIN [newuser10] WITH PASSWORD = @hashedpass HASHED;
SELECT @hashedpass;
固定値の代わりに変数を使用してSQLでログインのパスワードを更新する方法を理解するのを手伝ってくれる人はいますか?
前もって感謝します
アップデート
チャーリーからの提案に基づいて、次のことも試しました
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 Incorrect Syntax new '@password' が生成されます。パラメータをブレースすると
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;
}
}
次に、PASSWORD の近くで sqlException Incorrect syntax を生成します。
Update2
チャーリーからの更新された提案を使用して、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));
クエリ文字列が適切に形成されているように見えますが、次の SQLException がスローされます。
編集
もう少し読んだ後、@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 インジェクションの可能性が最小限に抑えられますが、これは最も望ましい方法ではありません。
-ありがとう