ImpersonateOnSerializingReplyMessageProperty.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. //------------------------------------------------------------------------------------------------------
  2. // <copyright file="ImpersonateOnSerializingReplyMessageProperty.cs" company="Microsoft Corporation">
  3. // Copyright (c) Microsoft Corporation. All rights reserved.
  4. // </copyright>
  5. //----------------------------------------------------------------------------------------------------
  6. namespace System.ServiceModel.Security
  7. {
  8. using System.Runtime;
  9. using System.Security;
  10. using System.Security.Principal;
  11. using System.ServiceModel;
  12. using System.ServiceModel.Channels;
  13. using System.ServiceModel.Dispatcher;
  14. using System.ServiceModel.Diagnostics;
  15. /// <summary>
  16. /// The helper class to enable impersonation while serializing the body of the reply message.
  17. /// </summary>
  18. public class ImpersonateOnSerializingReplyMessageProperty : IMessageProperty
  19. {
  20. const string PropertyName = "ImpersonateOnSerializingReplyMessageProperty";
  21. MessageRpc rpc;
  22. internal ImpersonateOnSerializingReplyMessageProperty(ref MessageRpc rpc)
  23. {
  24. this.rpc = rpc;
  25. }
  26. /// <summary>
  27. /// Gets the name of the message property.
  28. /// </summary>
  29. public static string Name
  30. {
  31. get { return PropertyName; }
  32. }
  33. /// <summary>
  34. /// Gets the ImpersonateOnSerializingReplyMessageProperty property from a message.
  35. /// </summary>
  36. /// <param name="message">The message to extract the property from.</param>
  37. /// <param name="property">An output paramter to hold the ImpersonateOnSerializingReplyMessageProperty property.</param>
  38. /// <returns>True if the ImpersonateOnSerializingReplyMessageProperty property was found.</returns>
  39. public static bool TryGet(Message message, out ImpersonateOnSerializingReplyMessageProperty property)
  40. {
  41. if (message == null)
  42. {
  43. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
  44. }
  45. return TryGet(message.Properties, out property);
  46. }
  47. /// <summary>
  48. /// Gets the ImpersonateOnSerializingReplyMessageProperty property from MessageProperties.
  49. /// </summary>
  50. /// <param name="properties">The MessagePropeties object.</param>
  51. /// <param name="property">An output paramter to hold the ImpersonateOnSerializingReplyMessageProperty property.</param>
  52. /// <returns>True if the ImpersonateOnSerializingReplyMessageProperty property was found.</returns>
  53. public static bool TryGet(MessageProperties properties, out ImpersonateOnSerializingReplyMessageProperty property)
  54. {
  55. if (properties == null)
  56. {
  57. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("properties");
  58. }
  59. object value = null;
  60. if (properties.TryGetValue(PropertyName, out value))
  61. {
  62. property = value as ImpersonateOnSerializingReplyMessageProperty;
  63. }
  64. else
  65. {
  66. property = null;
  67. }
  68. return property != null;
  69. }
  70. /// <summary>
  71. /// Creates a copy of the message property.
  72. /// </summary>
  73. /// <returns>Returns a copy of the message property.</returns>
  74. public IMessageProperty CreateCopy()
  75. {
  76. ImpersonateOnSerializingReplyMessageProperty result = new ImpersonateOnSerializingReplyMessageProperty(ref this.rpc);
  77. return result;
  78. }
  79. /// <summary>
  80. /// Starts Impersonating with the caller's context if impersonation is enabled on the service and sets the appropriate principal on the thread as per the service configuration.
  81. /// </summary>
  82. /// <param name="impersonationContext">The impersonated context.</param>
  83. /// <param name="originalPrincipal">The original principal on the thread before invoking this method.</param>
  84. /// <param name="isThreadPrincipalSet">The value determines if the principal was set on the thread by the method.</param>
  85. /// <returns>Returns false if operation context was not available to impersonate.</returns>
  86. [Fx.Tag.SecurityNote(Critical = "Calls SecurityCritical method StartImpersonation.", Safe = "Manages the result of impersonation and properly Disposes it.")]
  87. [SecuritySafeCritical]
  88. public void StartImpersonation(out IDisposable impersonationContext, out IPrincipal originalPrincipal, out bool isThreadPrincipalSet)
  89. {
  90. impersonationContext = null;
  91. originalPrincipal = null;
  92. isThreadPrincipalSet = false;
  93. if (OperationContext.Current != null)
  94. {
  95. EndpointDispatcher endpointDispatcher = OperationContext.Current.EndpointDispatcher;
  96. if (endpointDispatcher != null)
  97. {
  98. DispatchRuntime dispatchRuntime = endpointDispatcher.DispatchRuntime;
  99. ImmutableDispatchRuntime runtime = dispatchRuntime.GetRuntime();
  100. if (runtime != null && runtime.SecurityImpersonation != null)
  101. {
  102. runtime.SecurityImpersonation.StartImpersonation(ref this.rpc, out impersonationContext, out originalPrincipal, out isThreadPrincipalSet);
  103. }
  104. }
  105. }
  106. }
  107. /// <summary>
  108. /// Reverts impersonation and sets the original principal on the thread.
  109. /// </summary>
  110. /// <param name="impersonationContext">The impersonation context to revert.</param>
  111. /// <param name="originalPrincipal">The original principal to set on the thread.</param>
  112. /// <param name="isThreadPrincipalSet">The value determines if the thread principal was set during impersonation.</param>
  113. /// <returns>Returns false if operation context was not available to revert the impersonation.</returns>
  114. [Fx.Tag.SecurityNote(Critical = "Calls SecurityCritical method StartImpersonation.", Safe = "Manages the result of impersonation and properly Disposes it.")]
  115. [SecuritySafeCritical]
  116. public void StopImpersonation(IDisposable impersonationContext, IPrincipal originalPrincipal, bool isThreadPrincipalSet)
  117. {
  118. if (OperationContext.Current != null)
  119. {
  120. EndpointDispatcher endpointDispatcher = OperationContext.Current.EndpointDispatcher;
  121. if (endpointDispatcher != null)
  122. {
  123. DispatchRuntime dispatchRuntime = endpointDispatcher.DispatchRuntime;
  124. ImmutableDispatchRuntime runtime = dispatchRuntime.GetRuntime();
  125. if (runtime != null && runtime.SecurityImpersonation != null)
  126. {
  127. runtime.SecurityImpersonation.StopImpersonation(ref this.rpc, impersonationContext, originalPrincipal, isThreadPrincipalSet);
  128. }
  129. }
  130. }
  131. }
  132. }
  133. }