@@ -26,24 +26,78 @@ private protected virtual void Initialize()
26
26
{
27
27
}
28
28
29
- protected abstract void GenerateSspiClientContext ( ReadOnlySpan < byte > incomingBlob , IBufferWriter < byte > outgoingBlobWriter , ReadOnlySpan < string > serverSpns ) ;
29
+ protected abstract bool GenerateSspiClientContext ( ReadOnlySpan < byte > incomingBlob , IBufferWriter < byte > outgoingBlobWriter , SqlAuthenticationParameters authParams ) ;
30
30
31
31
internal void SSPIData ( ReadOnlySpan < byte > receivedBuff , IBufferWriter < byte > outgoingBlobWriter , string serverSpn )
32
- => SSPIData ( receivedBuff , outgoingBlobWriter , new [ ] { serverSpn } ) ;
32
+ {
33
+ using var _ = TrySNIEventScope . Create ( nameof ( SSPIContextProvider ) ) ;
33
34
34
- internal void SSPIData ( ReadOnlySpan < byte > receivedBuff , IBufferWriter < byte > outgoingBlobWriter , string [ ] serverSpns )
35
+ if ( ! RunGenerateSspiClientContext ( receivedBuff , outgoingBlobWriter , serverSpn ) )
36
+ {
37
+ // If we've hit here, the SSPI context provider implementation failed to generate the SSPI context.
38
+ SSPIError ( SQLMessage . SSPIGenerateError ( ) , TdsEnums . GEN_CLIENT_CONTEXT ) ;
39
+ }
40
+ }
41
+
42
+ internal void SSPIData ( ReadOnlySpan < byte > receivedBuff , IBufferWriter < byte > outgoingBlobWriter , ReadOnlySpan < string > serverSpns )
35
43
{
36
- using ( TrySNIEventScope . Create ( nameof ( SSPIContextProvider ) ) )
44
+ using var _ = TrySNIEventScope . Create ( nameof ( SSPIContextProvider ) ) ;
45
+
46
+ foreach ( var serverSpn in serverSpns )
37
47
{
38
- try
39
- {
40
- GenerateSspiClientContext ( receivedBuff , outgoingBlobWriter , serverSpns ) ;
41
- }
42
- catch ( Exception e )
48
+ if ( RunGenerateSspiClientContext ( receivedBuff , outgoingBlobWriter , serverSpn ) )
43
49
{
44
- SSPIError ( e . Message + Environment . NewLine + e . StackTrace , TdsEnums . GEN_CLIENT_CONTEXT ) ;
50
+ return ;
45
51
}
46
52
}
53
+
54
+ // If we've hit here, the SSPI context provider implementation failed to generate the SSPI context.
55
+ SSPIError ( SQLMessage . SSPIGenerateError ( ) , TdsEnums . GEN_CLIENT_CONTEXT ) ;
56
+ }
57
+
58
+ private bool RunGenerateSspiClientContext ( ReadOnlySpan < byte > incomingBlob , IBufferWriter < byte > outgoingBlobWriter , string serverSpn )
59
+ {
60
+ var authParams = CreateSqlAuthParams ( _parser . Connection , serverSpn ) ;
61
+
62
+ try
63
+ {
64
+ #if NET8_0_OR_GREATER
65
+ SqlClientEventSource . Log . TryTraceEvent ( "{0}.{1} | Info | Session Id {2}, SPN={3}" , GetType ( ) . FullName ,
66
+ nameof ( GenerateSspiClientContext ) , _physicalStateObj . SessionId , serverSpn ) ;
67
+ #else
68
+ SqlClientEventSource . Log . TryTraceEvent ( "{0}.{1} | Info | SPN={1}" , GetType ( ) . FullName ,
69
+ nameof ( GenerateSspiClientContext ) , serverSpn ) ;
70
+ #endif
71
+
72
+ return GenerateSspiClientContext ( incomingBlob , outgoingBlobWriter , authParams ) ;
73
+ }
74
+ catch ( Exception e )
75
+ {
76
+ SSPIError ( e . Message + Environment . NewLine + e . StackTrace , TdsEnums . GEN_CLIENT_CONTEXT ) ;
77
+ return false ;
78
+ }
79
+ }
80
+
81
+ private static SqlAuthenticationParameters CreateSqlAuthParams ( SqlInternalConnectionTds connection , string serverSpn )
82
+ {
83
+ var auth = new SqlAuthenticationParameters . Builder (
84
+ authenticationMethod : connection . ConnectionOptions . Authentication ,
85
+ resource : null ,
86
+ authority : null ,
87
+ serverName : serverSpn ,
88
+ connection . ConnectionOptions . InitialCatalog ) ;
89
+
90
+ if ( connection . ConnectionOptions . UserID is { } userId )
91
+ {
92
+ auth . WithUserId ( userId ) ;
93
+ }
94
+
95
+ if ( connection . ConnectionOptions . Password is { } password )
96
+ {
97
+ auth . WithPassword ( password ) ;
98
+ }
99
+
100
+ return auth ;
47
101
}
48
102
49
103
protected void SSPIError ( string error , string procedure )
0 commit comments