SSPI和SQL Server Windows身份验证 [英] SSPI and SQL Server Windows Authentication

查看:235
本文介绍了SSPI和SQL Server Windows身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Windows身份验证连接到SQL Server.可以在 NetCpp .

I'm trying to connect to SQL Server with Windows Authentication. Microsoft C# and C sources can be found at NetCpp.

在Delphi中,我有这样的代码:

In Delphi I have code like this:

function TTDS7SSPI.MakeSPN: string;
const
    szBracketedInstanceFormatString = '%s/[%s]:%s';
    szBracketedEmptyInstanceFormatString = '%s/[%s]%s';
    szClearInstanceFormatString = '%s/%s:%s';
    szClearEmptyInstanceFormatString = '%s/%s%s';
  szBracketedFormatString = '%s/[%s]:%d';
  szClearFormatString = '%s/%s:%d';
var
  NeedBrackets: Boolean;
  FmtString: string;
begin
  NeedBrackets := Pos(':', FHostName) > 0;
  if FInstanceName <> '' then begin
    // Make an instance name based SPN, i.e. MSSQLSvc/FQDN:instancename
    if NeedBrackets then begin
      if FInstanceName = '' then
        FmtString := szBracketedEmptyInstanceFormatString
      else
        FmtString := szBracketedInstanceFormatString;
    end
    else begin
      if FInstanceName = '' then
        FmtString := szClearEmptyInstanceFormatString
      else
        FmtString := szClearInstanceFormatString;
    end;
    Result := Format(FmtString, [SQL_SERVICECLASS, FHostName, FInstanceName]);
  end
  else begin
    // Make a TCP port based SPN, i.e. MSSQLSvc/FQDN:TcpPort
    Assert(FPort > 0);
    if NeedBrackets then
      FmtString := szBracketedFormatString
    else
      FmtString := szClearFormatString;
    Result := Format(FmtString, [SQL_SERVICECLASS, FHostName, FPort]);
  end;
end;

function TTDS7SSPI.GetAuth: TBytes;
var
  pkgInfo: PSecPkgInfo;
  SecBuf: SecBuffer;
  BuffDesc: SecBufferDesc;
  status: SECURITY_STATUS;
  attrs: Cardinal;
  tsExpiry: TTimeStamp;
const
  NEG_STR: WideString = 'Negotiate'; // 'NTLM'; // 'Kerberos';
begin
  Result := nil;

  status := QuerySecurityPackageInfo({$IFDEF FPC}PSecChar{$ELSE}PSecWChar{$ENDIF}(NEG_STR), pkgInfo);
  if status <> SEC_E_OK then
    raise Exception.CreateFmt('Couldn''t query package info for %s, error %X', [NEG_STR, status]);
  FMaxMessageLen := pkgInfo.cbMaxToken; // 4096;
  FreeContextBuffer(pkgInfo);

  TTimeStamp(tsExpiry).QuadPart := 0;
  status := AcquireCredentialsHandle(nil, {$IFDEF FPC}PSecChar{$ELSE}PSecWChar{$ENDIF}(NEG_STR), SECPKG_CRED_BOTH, // SECPKG_CRED_OUTBOUND
    nil, nil, nil, nil, @FCred, tsExpiry); // tsExpiry as var parameter
  if status <> SEC_E_OK then
    raise Exception.CreateFmt('AcquireCredentialsHandle error %X', [status]);

  BuffDesc.ulVersion := SECBUFFER_VERSION;
  BuffDesc.cBuffers := 1;
  BuffDesc.pBuffers := @SecBuf;

  SecBuf.BufferType := SECBUFFER_TOKEN;
  SetLength(Result, FMaxMessageLen);
  SecBuf.pvBuffer := @Result[0];
  SecBuf.cbBuffer := FMaxMessageLen;

  {status := QueryCredentialsAttributes(@FCred, SECPKG_CRED_ATTR_NAMES, @attrName);
  if status = SEC_E_OK then
    FSPN := PWideChar(attrName.sUserName)
  else}
    // For DAC use "localhost" instead of the server name (Microsoft)
    FSPN := WideString(MakeSPN);

  FContextAttrib := ISC_REQ_DELEGATE or ISC_REQ_MUTUAL_AUTH or ISC_REQ_INTEGRITY or ISC_REQ_EXTENDED_ERROR;
  // ISC_REQ_CONFIDENTIALITY or ISC_REQ_REPLAY_DETECT or ISC_REQ_CONNECTION;
  // $8C03C;
  // ISC_REQ_MUTUAL_AUTH or ISC_REQ_IDENTIFY or ISC_REQ_CONFIDENTIALITY or ISC_REQ_REPLAY_DETECT or ISC_REQ_SEQUENCE_DETECT or ISC_REQ_CONNECTION or ISC_REQ_DELEGATE;

  status := InitializeSecurityContext(@FCred, nil, {$IFDEF FPC}PSecChar{$ELSE}PSecWChar{$ENDIF}(FSPN),
    FContextAttrib,
    0, SECURITY_NATIVE_DREP,    nil, 0, @FCredCtx, @BuffDesc, attrs, @tsExpiry);
  if status <= 0 then
    raise Exception.CreateFmt('InitializeSecurityContext error %X', [status]);

  if (status = SEC_I_COMPLETE_NEEDED) or (status = SEC_I_COMPLETE_AND_CONTINUE) {or (status = SEC_I_CONTINUE_NEEDED)} then begin
    status := CompleteAuthToken(@FCredCtx, @BuffDesc);
    if status <> SEC_E_OK then begin
      FreeCredentialsHandle(@FCred);
      Result := nil;
      raise Exception.CreateFmt('CompleteAuthToken error %X', [status]);
    end;
  end
  else if (status <> SEC_E_OK) and (status <> SEC_I_CONTINUE_NEEDED) then begin
    // SEC_I_CONTINUE_NEEDED
    // The client must send the output token to the server and wait for a return token.
    // The returned token is then passed in another call to InitializeSecurityContext (Negotiate). The output token can be empty
    FreeCredentialsHandle(@FCred);
    Result := nil;
    raise Exception.CreateFmt('InitializeSecurityContext error %X', [status]);
  end;

  SetLength(Result, SecBuf.cbBuffer);
end;

function TTDS7SSPI.ParseServerResponse(Buf: TBytes): TBytes;
var
  InSecBuff, OutSecBuff: SecBuffer;
  InBuffDesc, OutBuffDesc: SecBufferDesc;
  status: SECURITY_STATUS;
  attrs: Cardinal;
  tsExpiry: TTimeStamp;
begin
  Assert((Length(Buf) >= 32) or (Length(Buf) <= Integer(FMaxMessageLen)));

  InBuffDesc.ulVersion := SECBUFFER_VERSION;
  InBuffDesc.cBuffers := 1;
  InBuffDesc.pBuffers := @InSecBuff;

  OutBuffDesc.ulVersion := SECBUFFER_VERSION;
  OutBuffDesc.cBuffers := 1;
  OutBuffDesc.pBuffers := @OutSecBuff;

  Assert(Length(Buf) > 0);
  InSecBuff.BufferType := SECBUFFER_TOKEN;
  InSecBuff.pvBuffer := @Buf[0];
  InSecBuff.cbBuffer := Length(Buf);

  OutSecBuff.BufferType := SECBUFFER_TOKEN;
  SetLength(Result, FMaxMessageLen);
  OutSecBuff.pvBuffer := @Result[0];
  OutSecBuff.cbBuffer := Length(Result);

  status := InitializeSecurityContext(@FCred, @FCredCtx, {$IFDEF FPC}PSecChar{$ELSE}PSecWChar{$ENDIF}(FSPN),
    FContextAttrib,
    0, SECURITY_NATIVE_DREP, @InBuffDesc,   0, @FCredCtx, @OutBuffDesc, attrs, @tsExpiry);

  if status <> SEC_E_OK then begin
    Result := nil;
    raise Exception.CreateFmt('InitializeSecurityContext error %X', [status]);
  end
  else
    SetLength(Result, OutSecBuff.cbBuffer);
end;

我得到的SPN就像MSSQLSvc/3R-XP:MSSQL2008(3R-XP上的客户端和服务器,实例MSSQL2008). InitializeSecurityContext的状态为SEC_I_CONTINUE_NEEDED.一切正常,没有错误,只是服务器不返回查询中的任何行,仅返回TDS_DONE.

The SPN I got is like MSSQLSvc/3R-XP:MSSQL2008 (client and server both on 3R-XP, instance MSSQL2008). InitializeSecurityContext has status SEC_I_CONTINUE_NEEDED. Everything works without errors except that the server does not return any of the rows from the query, only TDS_DONE.

SQL Server日志显示:

The SQL Server log says:

用户"3R-XP \ me"成功登录.使用Windows身份验证进行的连接. [客户:192.168.0.100]

Login succeeded for user '3R-XP\me'. Connection made using Windows authentication. [CLIENT: 192.168.0.100]

我还尝试比较OLEDB和我发送和接收的数据.由于SSL加密,我看不到OLEDB发送的第一个数据包.矿山SSPI登录数据

Also I tried to compare OLEDB and mine data sent and received. I can't see the first packet sent by OLEDB due to SSL encryption. Mine SSPI login data

4E 54 4C 4D 53 53   |  NTLMSS
50 00 01 00 00 00 97 B2 08 E2 09 00 09 00 2D 00   |  P.............-.
00 00 05 00 05 00 28 00 00 00 05 01 28 0A 00 00   |  ......(.....(...
00 0F 33 52 2D 58 50 57 4F 52 4B 47 52 4F 55 50   |  ..3R-XPWORKGROUP

OLEDB的服务器响应(由于WinPCAP只能与真实适配器一起使用而连接到另一台PC,因此主机名是"hp-6320",客户端名是"3R-Win7"):

The server response of OLEDB (connect to another PC due to the fact that WinPCAP can only work with real adapters, so the host name is 'hp-6320' and the client name is '3R-Win7' here) is:

000000 04 01 00 A5 00 00 01 00 ED 9A 00 4E 54 4C 4D 53   |  ...........NTLMS
000010 53 50 00 02 00 00 00 0E 00 0E 00 38 00 00 00 15   |  SP.........8....
000020 82 8A E2 A3 6E FC 4B 59 86 13 D6 00 00 00 00 00   |  ....n.KY........
000030 00 00 00 54 00 54 00 46 00 00 00 05 01 28 0A 00   |  ...T.T.F.....(..
000040 00 00 0F 48 00 50 00 2D 00 36 00 33 00 32 00 30   |  ...H.P.-.6.3.2.0
000050 00 02 00 0E 00 48 00 50 00 2D 00 36 00 33 00 32   |  .....H.P.-.6.3.2
000060 00 30 00 01 00 0E 00 48 00 50 00 2D 00 36 00 33   |  .0.....H.P.-.6.3
000070 00 32 00 30 00 04 00 0E 00 68 00 70 00 2D 00 36   |  .2.0.....h.p.-.6
000080 00 33 00 32 00 30 00 03 00 0E 00 68 00 70 00 2D   |  .3.2.0.....h.p.-
000090 00 36 00 33 00 32 00 30 00 06 00 04 00 01 00 00   |  .6.3.2.0........
0000A0 00 00 00 00 00   |  .....

我的代码(机器"3R-XP")对SQL Server的响应

SQL Server response with my code (machine '3R-XP')

04 01 00 89 00 00 01 00   |  ........
ED 7E 00 4E 54 4C 4D 53 53 50 00 02 00 00 00 0A   |  .~.NTLMSSP......
00 0A 00 38 00 00 00 15 C2 8A E2 B0 17 7A 15 A4   |  ...8.........z..
21 2A 96 38 E6 3D 01 00 00 00 00 3C 00 3C 00 42   |  !*.8.=.....<.<.B
00 00 00 05 01 28 0A 00 00 00 0F 33 00 52 00 2D   |  .....(.....3.R.-
00 58 00 50 00 02 00 0A 00 33 00 52 00 2D 00 58   |  .X.P.....3.R.-.X
00 50 00 01 00 0A 00 33 00 52 00 2D 00 58 00 50   |  .P.....3.R.-.X.P
00 04 00 0A 00 33 00 52 00 2D 00 58 00 50 00 03   |  .....3.R.-.X.P..
00 0A 00 33 00 52 00 2D 00 58 00 50 00 00 00 00   |  ...3.R.-.X.P....
00   |  .

看起来一样.但是在第二次InitializeSecurityContext之后,OLEDB返回该值

It looks the same. But after that second InitializeSecurityContext OLEDB returns the value

000000 11 01 01 A2 00 00 01 00 4E 54 4C 4D 53 53 50 00   |  ........NTLMSSP.
000010 03 00 00 00 18 00 18 00 78 00 00 00 FA 00 FA 00   |  ........x.......
000020 90 00 00 00 0E 00 0E 00 58 00 00 00 04 00 04 00   |  ........X.......
000030 66 00 00 00 0E 00 0E 00 6A 00 00 00 10 00 10 00   |  f.......j.......
000040 8A 01 00 00 15 82 88 E2 06 01 B1 1D 00 00 00 0F   |  ................
000050 18 B1 57 6E 0F 9B BE 6A AF 2A D4 76 8D B2 19 72   |  ..Wn...j.*.v...r
000060 33 00 52 00 2D 00 57 00 69 00 6E 00 37 00 6D 00   |  3.R.-.W.i.n.7.m.
000070 65 00 33 00 52 00 2D 00 57 00 49 00 4E 00 37 00   |  e.3.R.-.W.I.N.7.
000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   |  ................
000090 00 00 00 00 00 00 00 00 3B 97 82 77 95 74 1E 7C   |  ........;..w.t.|
0000A0 A8 D1 C5 2F 5F 82 7A 9C 01 01 00 00 00 00 00 00   |  .../_.z.........
0000B0 EE 4C 92 1E 68 10 D1 01 B3 93 23 3B A9 14 0C EF   |  .L..h.....#;....
0000C0 00 00 00 00 02 00 0E 00 48 00 50 00 2D 00 36 00   |  ........H.P.-.6.
0000D0 33 00 32 00 30 00 01 00 0E 00 48 00 50 00 2D 00   |  3.2.0.....H.P.-.
0000E0 36 00 33 00 32 00 30 00 04 00 0E 00 68 00 70 00   |  6.3.2.0.....h.p.
0000F0 2D 00 36 00 33 00 32 00 30 00 03 00 0E 00 68 00   |  -.6.3.2.0.....h.
000100 70 00 2D 00 36 00 33 00 32 00 30 00 06 00 04 00   |  p.-.6.3.2.0.....
000110 01 00 00 00 08 00 30 00 30 00 00 00 00 00 00 00   |  ......0.0.......
000120 01 00 00 00 00 20 00 00 9B 51 53 D8 0E 0F C8 EB   |  ..... ...QS.....
000130 F9 11 AB 3D B3 FB 86 F6 D0 D2 97 3C 4C F7 E0 48   |  ...=.......<L..H
000140 C4 BF 2F 60 DC CA AB 10 0A 00 10 00 14 5E 11 19   |  ../`.........^..
000150 42 DC 79 32 B1 DC 04 C0 C9 48 8D 2C 09 00 2A 00   |  B.y2.....H.,..*.
000160 4D 00 53 00 53 00 51 00 4C 00 53 00 76 00 63 00   |  M.S.S.Q.L.S.v.c.
000170 2F 00 68 00 70 00 2D 00 36 00 33 00 32 00 30 00   |  /.h.p.-.6.3.2.0.
000180 3A 00 31 00 34 00 33 00 33 00 00 00 00 00 00 00   |  :.1.4.3.3.......
000190 00 00 7D 45 28 4F E6 4B 38 90 BD F6 91 61 A7 E8   |  ..}E(O.K8....a..
0001A0 8D 26   |  .&

对于我的代码,它返回

11 01 00 50 00 00 00 00 4E 54 4C 4D 53 53 50 00   |  ...P....NTLMSSP.
03 00 00 00 00 00 00 00 48 00 00 00 00 00 00 00   |  ........H.......
48 00 00 00 00 00 00 00 48 00 00 00 00 00 00 00   |  H.......H.......
48 00 00 00 00 00 00 00 48 00 00 00 00 00 00 00   |  H.......H.......
48 00 00 00 15 C2 88 E2 05 01 28 0A 00 00 00 0F   |  H.........(.....

您会看到所有结构都是空的(大小为0,分配为0,偏移量为48).有什么不对?如何解决这些问题?我已经尝试过其他标志等,结果相同甚至更差. OLEDB正常工作,因此服务器配置似乎正确.

As you can see all structures are empty (size 0, allocated 0, offset 48). Is there something wrong? How to fix that stuff? I've tried different flags etc already, the results are the same or even worse. OLEDB works so it seems that the server is configured properly.

推荐答案

使用WinAPIOverride,我发现身份验证使用Bindings(请参阅 InitializeSecurityContext 作为SECBUFFER_CHANNEL_BINDINGS成员.

With WinAPIOverride I found that authentication uses Bindings (see QueryContextAttributes SECPKG_ATTR_UNIQUE_BINDINGS) retrieved from SSL handshake in negotiation InitializeSecurityContext as SECBUFFER_CHANNEL_BINDINGS member.

到目前为止,我进行了基于SSPI的SSL握手,得到的Bindings看起来像

So far I made SSPI based SSL handshake, got Bindings that looks like

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   |  ................
00 00 00 00 00 00 00 00 17 00 00 00 20 00 00 00   |  ............ ...
74 6C 73 2D 75 6E 69 71 75 65 3A 66 55 6F 05 7F   |  tls-unique:fUo.
DD 90 31 4F 87 02 52   |  ..1O..R

发现,当客户端和服务器位于同一台计算机上时,那些空的NTLMSSP消息似乎是正确的(末尾有一些额外的内容),ODBC驱动程序发送类似

found that those empty NTLMSSP message seems proper (with some extra at the end) while client and server on same machine, ODBC driver sends like

A1 77 30 75 A0 03 0A 01 01 A2 5A 04 58 4E 54 4C .w0u......Z.XNTL
4D 53 53 50 00 03 00 00 00 00 00 00 00 58 00 00 MSSP.........X..
00 00 00 00 00 58 00 00 00 00 00 00 00 58 00 00 .....X.......X..
00 00 00 00 00 58 00 00 00 00 00 00 00 58 00 00 .....X.......X..
00 00 00 00 00 58 00 00 00 15 C2 88 E2 0A 00 5A .....X.........Z
29 00 00 00 0F 9E 3F 5C EE FF F1 AF 9A 44 4C 3A ).....?\.....DL:
6F C3 20 0F 8B A3 12 04 10 01 00 00 00 9C B1 60 o. ............`
36 3B 84 96 09 00 00 00 00                      6;.......  

远程最后的身份验证数据看起来像(ODBC驱动程序)

remote last authentication data looks like (ODBC driver)

4E 54 4C 4D 53 53 50 00 03 00 00 00 18 00 18 00 NTLMSSP.........
78 00 00 00 3C 01 3C 01 90 00 00 00 0E 00 0E 00 x...<.<.........
58 00 00 00 04 00 04 00 66 00 00 00 0E 00 0E 00 X.......f.......
6A 00 00 00 10 00 10 00 CC 01 00 00 15 82 88 E2 j...............
0A 00 5A 29 00 00 00 0F E0 87 5F 85 21 5A 73 17 ..Z)......_.!Zs.
04 6C 1A F5 9C BA F7 42 33 00 52 00 2D 00 57 00 .l.....B3.R.-.W.
69 00 6E 00 37 00 6D 00 65 00 33 00 52 00 2D 00 i.n.7.m.e.3.R.-.
57 00 49 00 4E 00 37 00 00 00 00 00 00 00 00 00 W.I.N.7.........
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
37 F2 38 62 5B 9C 7E 07 6F 89 9F 33 B2 92 3C 5C 7.8b[.~.o..3..<\
01 01 00 00 00 00 00 00 47 39 01 AD AC 4F D1 01 ........G9...O..
0D 36 47 06 7E 70 B8 A4 00 00 00 00 02 00 18 00 .6G.~p..........
48 00 50 00 2D 00 45 00 4C 00 49 00 54 00 45 00 H.P.-.E.L.I.T.E.
42 00 4F 00 4F 00 4B 00 01 00 18 00             B.O.O.K.....   

带有绑定的SSPI看起来稍微大一点(这里的8个首字节是TDS数据包头)

while SSPI with Bindings looks slightly bigger (8 first bytes here is TDS packet header)

11 01 01 EE 00 00 00 00 4E 54 4C 4D 53 53 50 00   |  ........NTLMSSP.
03 00 00 00 18 00 18 00 78 00 00 00 46 01 46 01   |  ........x...F.F.
90 00 00 00 0E 00 0E 00 58 00 00 00 04 00 04 00   |  ........X.......
66 00 00 00 0E 00 0E 00 6A 00 00 00 10 00 10 00   |  f.......j.......
D6 01 00 00 15 82 88 E2 0A 00 5A 29 00 00 00 0F   |  ..........Z)....
AD A5 C9 05 8C 25 E1 A9 C5 3E 17 BD 3D 19 E3 EB   |  .....%...>..=...
33 00 52 00 2D 00 57 00 69 00 6E 00 37 00 6D 00   |  3.R.-.W.i.n.7.m.
65 00 33 00 52 00 2D 00 57 00 49 00 4E 00 37 00   |  e.3.R.-.W.I.N.7.
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   |  ................
00 00 00 00 00 00 00 00 02 0B C5 A2 01 17 DB AC   |  ................
D8 26 9E 1B AF A1 77 32 01 01 00 00 00 00 00 00   |  .&....w2........
B8 28 90 0F AD 4F D1 01 41 F1 DF 7C BE 85 5D B6   |  .(...O..A..|..].
00 00 00 00 02 00 18 00 48 00 50 00 2D 00 45 00   |  ........H.P.-.E.
4C 00 49 00 54 00 45 00 42 00 4F 00 4F 00 4B 00   |  L.I.T.E.B.O.O.K.
01 00 18 00 48 00 50 00 2D 00 45 00 4C 00 49 00   |  ....H.P.-.E.L.I.
54 00 45 00 42 00 4F 00 4F 00 4B 00 04 00 18 00   |  T.E.B.O.O.K.....
48 00 50 00 2D 00 45 00 6C 00 69 00 74 00 65 00   |  H.P.-.E.l.i.t.e.
62 00 6F 00 6F 00 6B 00 03 00 18 00 48 00 50 00   |  b.o.o.k.....H.P.
2D 00 45 00 6C 00 69 00 74 00 65 00 62 00 6F 00   |  -.E.l.i.t.e.b.o.
6F 00 6B 00 07 00 08 00 B8 28 90 0F AD 4F D1 01   |  o.k......(...O..
06 00 04 00 02 00 00 00 08 00 30 00 30 00 00 00   |  ..........0.0...
00 00 00 00 01 00 00 00 00 20 00 00 DC 75 9C 98   |  ......... ...u..
70 C7 28 D7 BC C7 1E 14 48 70 0E 3B 8B A4 94 7C   |  p.(.....Hp.;...|
32 05 44 FD 85 5F D3 54 DB 6C 84 22 0A 00 10 00   |  2.D.._.T.l."....
B1 3B 92 CC 6C 5B E2 CD 0F 24 19 5F 6F 73 47 73   |  .;..l[...$._osGs
09 00 3E 00 4D 00 53 00 53 00 51 00 4C 00 53 00   |  ..>.M.S.S.Q.L.S.
76 00 63 00 2F 00 48 00 50 00 2D 00 45 00 4C 00   |  v.c./.H.P.-.E.L.
49 00 54 00 45 00 42 00 4F 00 4F 00 4B 00 3A 00   |  I.T.E.B.O.O.K.:.
4D 00 53 00 53 00 51 00 4C 00 32 00 30 00 30 00   |  M.S.S.Q.L.2.0.0.
38 00 00 00 00 00 00 00 00 00 00 00 00 00 F0 46   |  8..............F
20 EB 45 EC C8 67 9F E3 45 45 9C 79 76 47   |   .E..g..EE.yvG

QueryContextAttributes(@FCtxHandle,SECPKG_ATTR_NEGOTIATION_INFO,@NegInfo)返回状态SECPKG_NEGOTIATION_COMPLETE,因此一切都很好,服务器日志显示身份验证成功",但仍然没有足够的权限来获取查询结果或服务器错误,例如"Cannot find the object "all_types" because it does not exist or you do not have permissions",而简单的查询(例如"SET LOCK TIMEOUT 100")运行时不会出现错误.

QueryContextAttributes(@FCtxHandle, SECPKG_ATTR_NEGOTIATION_INFO, @NegInfo) returns state SECPKG_NEGOTIATION_COMPLETE so everything suppose to be fine, server log shows that "Authentication successful" but there is still not enough rights to get results of queries or server errors like "Cannot find the object "all_types" because it does not exist or you do not have permissions" while simple queries like "SET LOCK TIMEOUT 100" runs without errors.

因此,我认为在自己的创建者看来,Windows身份验证似乎不够安全,无法允许某些第三方应用程序使用它. Guest帐户已启用,并具有读取/写入数据的权限,并且可以通过ODBC驱动程序工作.

So my thoughts that Windows Authentication in the eyes of own creator doesn't looks secure enough to allow it to some third-party applications. Guest account enabled and have permissions to read/write data and it works through ODBC driver.

这篇关于SSPI和SQL Server Windows身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆