当您捕获 18488 错误时,您需要显示自己的“更改密码”对话框,并使用连接字符串属性"Old Password"
/ "Password"
viaSQL Native Client
作为您的提供者(即Provider=SQLNCLI10
或SQLNCLI.1
)。
这是我用来测试的一个小代码:
procedure TForm1.Button1Click(Sender: TObject);
begin
// 12345 is the "old password"
ADOConnection1.ConnectionString := 'Provider=SQLOLEDB.1;Password=12345;User ID=test;Initial Catalog=test;Data Source=127.0.0.1;Persist Security Info=True;';
try
ADOConnection1.Open;
except
if Assigned(ADOConnection1.Errors) and (ADOConnection1.Errors.Count > 0) and
(ADOConnection1.Errors.Item[0].NativeError = 18488) then
begin
// show your "change password" dialog... new password is 67890
ADOConnection1.ConnectionString := 'Provider=SQLNCLI10.1;Old Password=12345;Password=67890;User ID=test;Initial Catalog=test;Data Source=127.0.0.1;Persist Security Info=True;';
ADOConnection1.Open; // this will login and change the password
// OPTIONAL (unless you use SQLNCLI10.1 anyway)
// you may close the connection and re-open with your original provider and new password
ADOConnection1.Close;
ADOConnection1.ConnectionString := 'Provider=SQLOLEDB.1;Password=67890;User ID=test;Initial Catalog=test;Data Source=127.0.0.1;Persist Security Info=True;';
ADOConnection1.Open;
end
else
raise;
end;
ShowMessage('Login OK');
end;
我的回答是基于这些读数:
当您强制密码过期并在 SQL 服务器上使用“用户必须在下次登录时更改密码”选项时,这是从客户端更改密码的官方方法。
如果在用户机器上安装 SQL Server Native Client 是一个问题,我可以考虑更多选项:
- 创建一个 Web 服务(在您的服务器上),该服务将负责更改用户的密码,提供旧/新密码并将状态返回给您的客户端。
- 以“超级用户”身份连接(例如
sa
),并更改用户/登录密码。这意味着您需要在客户端计算机上保存该用户名/密码(恕我直言,从安全角度来看这是个坏主意,但可能可行)。- 未经测试
- 不要使用“用户下次登录时必须更改密码”来创建 SQL 登录。这是我最喜欢的解决方案。