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 147 148 149 150 151 152 153 154 155
|
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.Runtime;
using System.Security.Cryptography;
using System.Security.Authentication.ExtendedProtection;
using System.ServiceModel.Diagnostics;
namespace System.ServiceModel.Security.Tokens
{
/// <summary>
/// The ProviderBackedSecurityToken was added for the ChannelBindingToken work for Win7.
/// It is used to delay the resolution of a token until it is needed.
/// For the CBT, this delay is necessary as the CBT is not available until SecurityAppliedMessage.OnWriteMessage is called.
/// The CBT binds a token to the
/// </summary>
internal class ProviderBackedSecurityToken : SecurityToken
{
SecurityTokenProvider _tokenProvider;
// Double-checked locking pattern requires volatile for read/write synchronization
volatile SecurityToken _securityToken;
TimeSpan _timeout;
ChannelBinding _channelBinding;
object _lock;
/// <summary>
/// Constructor to create an instance of this class.
/// </summary>
/// <param name="securityToken">SecurityToken that represents the SecurityTokenElement element.</param>
public ProviderBackedSecurityToken( SecurityTokenProvider tokenProvider, TimeSpan timeout )
{
_lock = new object();
if ( tokenProvider == null )
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("tokenProvider"));
}
_tokenProvider = tokenProvider;
_timeout = timeout;
}
public SecurityTokenProvider TokenProvider
{
get { return _tokenProvider; }
}
public ChannelBinding ChannelBinding
{
set { _channelBinding = value; }
}
void ResolveSecurityToken()
{
if ( _securityToken == null )
{
lock ( _lock )
{
if ( _securityToken == null )
{
ClientCredentialsSecurityTokenManager.KerberosSecurityTokenProviderWrapper kerbTokenProvider = _tokenProvider
as ClientCredentialsSecurityTokenManager.KerberosSecurityTokenProviderWrapper;
if (kerbTokenProvider != null)
{
_securityToken = kerbTokenProvider.GetToken((new TimeoutHelper(_timeout)).RemainingTime(), _channelBinding);
}
else
{
_securityToken = _tokenProvider.GetToken((new TimeoutHelper(_timeout)).RemainingTime());
}
}
}
}
if ( _securityToken == null )
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new SecurityTokenException( SR.GetString( SR.SecurityTokenNotResolved, _tokenProvider.GetType().ToString() ) ) );
}
return;
}
public SecurityToken Token
{
get
{
if ( _securityToken == null )
{
ResolveSecurityToken();
}
return _securityToken;
}
}
public override string Id
{
get
{
if ( _securityToken == null )
{
ResolveSecurityToken();
}
return _securityToken.Id;
}
}
public override System.Collections.ObjectModel.ReadOnlyCollection<SecurityKey> SecurityKeys
{
get
{
if ( _securityToken == null )
{
ResolveSecurityToken();
}
return _securityToken.SecurityKeys;
}
}
public override DateTime ValidFrom
{
get
{
if ( _securityToken == null )
{
ResolveSecurityToken();
}
return _securityToken.ValidFrom;
}
}
public override DateTime ValidTo
{
get
{
if ( _securityToken == null )
{
ResolveSecurityToken();
}
return _securityToken.ValidTo;
}
}
}
}
|