2
0

SpnegoTokenAuthenticator.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.ServiceModel.Security
  5. {
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Collections.ObjectModel;
  9. using System.IdentityModel.Claims;
  10. using System.IdentityModel.Policy;
  11. using System.Net;
  12. using System.Runtime;
  13. using System.Security.Authentication.ExtendedProtection;
  14. using System.Security.Principal;
  15. using System.ServiceModel;
  16. using System.ServiceModel.Diagnostics;
  17. using System.Xml;
  18. using SafeCloseHandle = System.IdentityModel.SafeCloseHandle;
  19. using SafeFreeCredentials = System.IdentityModel.SafeFreeCredentials;
  20. sealed class SpnegoTokenAuthenticator : SspiNegotiationTokenAuthenticator
  21. {
  22. bool extractGroupsForWindowsAccounts;
  23. NetworkCredential serverCredential;
  24. bool allowUnauthenticatedCallers;
  25. SafeFreeCredentials credentialsHandle;
  26. public SpnegoTokenAuthenticator()
  27. : base()
  28. {
  29. // empty
  30. }
  31. // settings
  32. public bool ExtractGroupsForWindowsAccounts
  33. {
  34. get
  35. {
  36. return this.extractGroupsForWindowsAccounts;
  37. }
  38. set
  39. {
  40. this.CommunicationObject.ThrowIfDisposedOrImmutable();
  41. this.extractGroupsForWindowsAccounts = value;
  42. }
  43. }
  44. public NetworkCredential ServerCredential
  45. {
  46. get
  47. {
  48. return this.serverCredential;
  49. }
  50. set
  51. {
  52. this.CommunicationObject.ThrowIfDisposedOrImmutable();
  53. this.serverCredential = value;
  54. }
  55. }
  56. public bool AllowUnauthenticatedCallers
  57. {
  58. get
  59. {
  60. return this.allowUnauthenticatedCallers;
  61. }
  62. set
  63. {
  64. this.CommunicationObject.ThrowIfDisposedOrImmutable();
  65. this.allowUnauthenticatedCallers = value;
  66. }
  67. }
  68. // overrides
  69. public override XmlDictionaryString NegotiationValueType
  70. {
  71. get
  72. {
  73. return XD.TrustApr2004Dictionary.SpnegoValueTypeUri;
  74. }
  75. }
  76. public override void OnOpening()
  77. {
  78. base.OnOpening();
  79. if (this.credentialsHandle == null)
  80. {
  81. this.credentialsHandle = SecurityUtils.GetCredentialsHandle("Negotiate", this.serverCredential, true);
  82. }
  83. }
  84. public override void OnClose(TimeSpan timeout)
  85. {
  86. base.OnClose(timeout);
  87. FreeCredentialsHandle();
  88. }
  89. public override void OnAbort()
  90. {
  91. base.OnAbort();
  92. FreeCredentialsHandle();
  93. }
  94. void FreeCredentialsHandle()
  95. {
  96. if (this.credentialsHandle != null)
  97. {
  98. this.credentialsHandle.Close();
  99. this.credentialsHandle = null;
  100. }
  101. }
  102. protected override SspiNegotiationTokenAuthenticatorState CreateSspiState(byte[] incomingBlob, string incomingValueTypeUri)
  103. {
  104. ISspiNegotiation windowsNegotiation = new WindowsSspiNegotiation("Negotiate", this.credentialsHandle, DefaultServiceBinding);
  105. return new SspiNegotiationTokenAuthenticatorState(windowsNegotiation);
  106. }
  107. protected override ReadOnlyCollection<IAuthorizationPolicy> ValidateSspiNegotiation(ISspiNegotiation sspiNegotiation)
  108. {
  109. WindowsSspiNegotiation windowsNegotiation = (WindowsSspiNegotiation)sspiNegotiation;
  110. if (windowsNegotiation.IsValidContext == false)
  111. {
  112. throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new SecurityNegotiationException(SR.GetString(SR.InvalidSspiNegotiation)));
  113. }
  114. SecurityTraceRecordHelper.TraceServiceSpnego(windowsNegotiation);
  115. if (this.IsClientAnonymous)
  116. {
  117. return EmptyReadOnlyCollection<IAuthorizationPolicy>.Instance;
  118. }
  119. using (SafeCloseHandle contextToken = windowsNegotiation.GetContextToken())
  120. {
  121. WindowsIdentity windowsIdentity = new WindowsIdentity(contextToken.DangerousGetHandle(), windowsNegotiation.ProtocolName);
  122. SecurityUtils.ValidateAnonymityConstraint(windowsIdentity, this.AllowUnauthenticatedCallers);
  123. List<IAuthorizationPolicy> policies = new List<IAuthorizationPolicy>(1);
  124. WindowsClaimSet wic = new WindowsClaimSet( windowsIdentity, windowsNegotiation.ProtocolName, this.extractGroupsForWindowsAccounts, false );
  125. policies.Add(new System.IdentityModel.Policy.UnconditionalPolicy(wic, TimeoutHelper.Add(DateTime.UtcNow, base.ServiceTokenLifetime)));
  126. return policies.AsReadOnly();
  127. }
  128. }
  129. }
  130. }