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