167 lines
5.1 KiB
C#
167 lines
5.1 KiB
C#
|
//-----------------------------------------------------------------------------
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
namespace System.ServiceModel.Security
|
||
|
{
|
||
|
using System.IdentityModel.Selectors;
|
||
|
using System.IdentityModel.Tokens;
|
||
|
using System.Runtime;
|
||
|
using System.ServiceModel.Channels;
|
||
|
using System.ServiceModel.Description;
|
||
|
using System.ServiceModel.Dispatcher;
|
||
|
|
||
|
public class InfocardInteractiveChannelInitializer : IInteractiveChannelInitializer
|
||
|
{
|
||
|
ClientCredentials credentials;
|
||
|
Binding binding;
|
||
|
|
||
|
public InfocardInteractiveChannelInitializer(ClientCredentials credentials, Binding binding)
|
||
|
{
|
||
|
this.credentials = credentials;
|
||
|
this.binding = binding;
|
||
|
}
|
||
|
|
||
|
public Binding Binding
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return binding;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public virtual IAsyncResult BeginDisplayInitializationUI(IClientChannel channel, AsyncCallback callback, object state)
|
||
|
{
|
||
|
return new GetTokenUIAsyncResult(binding, channel, this.credentials, callback, state);
|
||
|
}
|
||
|
|
||
|
public virtual void EndDisplayInitializationUI(IAsyncResult result)
|
||
|
{
|
||
|
GetTokenUIAsyncResult.End(result);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
internal class GetTokenUIAsyncResult : AsyncResult
|
||
|
{
|
||
|
|
||
|
IClientChannel proxy;
|
||
|
ClientCredentials credentials;
|
||
|
Uri relyingPartyIssuer;
|
||
|
bool requiresInfoCard;
|
||
|
Binding binding;
|
||
|
|
||
|
|
||
|
static AsyncCallback callback = Fx.ThunkCallback(new AsyncCallback(GetTokenUIAsyncResult.Callback));
|
||
|
|
||
|
internal GetTokenUIAsyncResult(Binding binding,
|
||
|
IClientChannel channel,
|
||
|
ClientCredentials credentials,
|
||
|
AsyncCallback callback,
|
||
|
object state)
|
||
|
: base(callback, state)
|
||
|
{
|
||
|
this.credentials = credentials;
|
||
|
this.proxy = channel;
|
||
|
this.binding = binding;
|
||
|
this.CallBegin(true);
|
||
|
|
||
|
}
|
||
|
|
||
|
void CallBegin(bool completedSynchronously)
|
||
|
{
|
||
|
|
||
|
IAsyncResult result = null;
|
||
|
Exception exception = null;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
CardSpacePolicyElement[] chain;
|
||
|
SecurityTokenManager tokenManager = credentials.CreateSecurityTokenManager();
|
||
|
requiresInfoCard = InfoCardHelper.IsInfocardRequired(binding, credentials, tokenManager, proxy.RemoteAddress, out chain, out relyingPartyIssuer);
|
||
|
MessageSecurityVersion bindingSecurityVersion = InfoCardHelper.GetBindingSecurityVersionOrDefault(binding);
|
||
|
WSSecurityTokenSerializer tokenSerializer = WSSecurityTokenSerializer.DefaultInstance;
|
||
|
result = credentials.GetInfoCardTokenCallback.BeginInvoke(requiresInfoCard, chain, tokenManager.CreateSecurityTokenSerializer(bindingSecurityVersion.SecurityTokenVersion), callback, this);
|
||
|
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
if (Fx.IsFatal(e))
|
||
|
{
|
||
|
throw;
|
||
|
}
|
||
|
|
||
|
exception = e;
|
||
|
}
|
||
|
if (exception == null)
|
||
|
{
|
||
|
if (!result.CompletedSynchronously)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
this.CallEnd(result, out exception);
|
||
|
}
|
||
|
if (exception != null)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
this.CallComplete(completedSynchronously, null);
|
||
|
}
|
||
|
|
||
|
static void Callback(IAsyncResult result)
|
||
|
{
|
||
|
if (result.CompletedSynchronously)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
GetTokenUIAsyncResult outer = (GetTokenUIAsyncResult)result.AsyncState;
|
||
|
Exception exception = null;
|
||
|
|
||
|
outer.CallEnd(result, out exception);
|
||
|
outer.CallComplete(false, exception);
|
||
|
|
||
|
}
|
||
|
|
||
|
void CallEnd(IAsyncResult result, out Exception exception)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
SecurityToken token = credentials.GetInfoCardTokenCallback.EndInvoke(result);
|
||
|
|
||
|
ChannelParameterCollection channelParameters =
|
||
|
proxy.GetProperty<ChannelParameterCollection>();
|
||
|
|
||
|
if (null != channelParameters)
|
||
|
{
|
||
|
channelParameters.Add(new InfoCardChannelParameter(token, relyingPartyIssuer, requiresInfoCard));
|
||
|
}
|
||
|
exception = null;
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
if (Fx.IsFatal(e))
|
||
|
{
|
||
|
throw;
|
||
|
}
|
||
|
exception = e;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CallComplete(bool completedSynchronously, Exception exception)
|
||
|
{
|
||
|
this.Complete(completedSynchronously, exception);
|
||
|
}
|
||
|
|
||
|
internal static void End(IAsyncResult result)
|
||
|
{
|
||
|
AsyncResult.End<GetTokenUIAsyncResult>(result);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|