| | | 1 | | // Licensed to the .NET Foundation under one or more agreements. |
| | | 2 | | // The .NET Foundation licenses this file to you under the MIT license. |
| | | 3 | | |
| | | 4 | | using System; |
| | | 5 | | using System.Collections.Generic; |
| | | 6 | | using System.Collections.ObjectModel; |
| | | 7 | | using System.Globalization; |
| | | 8 | | using System.Runtime.Serialization; |
| | | 9 | | using System.Threading; |
| | | 10 | | using System.Threading.Tasks; |
| | | 11 | | using System.Xml; |
| | | 12 | | using CoreWCF.Channels; |
| | | 13 | | using CoreWCF.Description; |
| | | 14 | | using CoreWCF.Diagnostics; |
| | | 15 | | using CoreWCF.Dispatcher; |
| | | 16 | | using CoreWCF.IdentityModel.Claims; |
| | | 17 | | using CoreWCF.IdentityModel.Policy; |
| | | 18 | | using CoreWCF.IdentityModel.Selectors; |
| | | 19 | | using CoreWCF.IdentityModel.Tokens; |
| | | 20 | | using CoreWCF.Runtime; |
| | | 21 | | using CoreWCF.Security.Tokens; |
| | | 22 | | |
| | | 23 | | namespace CoreWCF.Security |
| | | 24 | | { |
| | | 25 | | internal class SecuritySessionSecurityTokenAuthenticator : CommunicationObjectSecurityTokenAuthenticator, IIssuanceS |
| | | 26 | | { |
| | 3 | 27 | | internal static readonly TimeSpan s_defaultSessionTokenLifetime = TimeSpan.MaxValue; |
| | | 28 | | internal const int DefaultMaxCachedSessionTokens = int.MaxValue; |
| | 3 | 29 | | internal static readonly SecurityStandardsManager s_defaultStandardsManager = SecurityStandardsManager.DefaultIn |
| | | 30 | | private bool _isClientAnonymous; |
| | | 31 | | private TimeSpan _sessionTokenLifetime; |
| | | 32 | | private ISecurityContextSecurityTokenCache _issuedTokenCache; |
| | | 33 | | private SecurityBindingElement _bootstrapSecurityBindingElement; |
| | | 34 | | private BindingContext _issuerBindingContext; |
| | | 35 | | private SecurityStandardsManager _standardsManager; |
| | | 36 | | private SecurityAlgorithmSuite _securityAlgorithmSuite; |
| | | 37 | | private SecurityKeyEntropyMode _keyEntropyMode; |
| | | 38 | | private TimeSpan _keyRenewalInterval; |
| | | 39 | | private SecurityTokenParameters _issuedTokenParameters; |
| | | 40 | | private Uri _listenUri; |
| | | 41 | | private string _sctUri; |
| | | 42 | | private IMessageFilterTable<EndpointAddress> _endpointFilterTable; |
| | | 43 | | private bool _shouldMatchRstWithEndpointFilter; |
| | | 44 | | private int _maximumConcurrentNegotiations; |
| | | 45 | | private TimeSpan _negotiationTimeout; |
| | 22 | 46 | | private readonly object _thisLock = new object(); |
| | | 47 | | |
| | 22 | 48 | | public SecuritySessionSecurityTokenAuthenticator() |
| | | 49 | | { |
| | 22 | 50 | | SessionTokenAuthenticator = new SecurityContextSecurityTokenAuthenticator(); |
| | 22 | 51 | | _sessionTokenLifetime = s_defaultSessionTokenLifetime; |
| | 22 | 52 | | _isClientAnonymous = false; |
| | 22 | 53 | | _standardsManager = s_defaultStandardsManager; |
| | 22 | 54 | | _keyEntropyMode = SecurityKeyEntropyMode.CombinedEntropy;// AcceleratedTokenProvider.defaultKeyEntropyMode; |
| | 22 | 55 | | _maximumConcurrentNegotiations = 128;// AcceleratedTokenAuthenticator.defaultServerMaxActiveNegotiations; |
| | 22 | 56 | | _negotiationTimeout = TimeSpan.Parse("00:01:00", CultureInfo.InvariantCulture); // AcceleratedTokenAuthentic |
| | 22 | 57 | | } |
| | | 58 | | |
| | 42 | 59 | | public IssuedSecurityTokenHandler IssuedSecurityTokenHandler { get; set; } |
| | | 60 | | |
| | 22 | 61 | | public RenewedSecurityTokenHandler RenewedSecurityTokenHandler { get; set; } |
| | | 62 | | |
| | 66 | 63 | | public SecurityServiceDispatcher SecurityServiceDispatcher { get; set; } |
| | | 64 | | |
| | | 65 | | public SecurityAlgorithmSuite SecurityAlgorithmSuite |
| | | 66 | | { |
| | | 67 | | get |
| | | 68 | | { |
| | 32 | 69 | | return _securityAlgorithmSuite; |
| | | 70 | | } |
| | | 71 | | set |
| | | 72 | | { |
| | 22 | 73 | | CommunicationObject.ThrowIfDisposedOrImmutable(); |
| | 22 | 74 | | _securityAlgorithmSuite = value; |
| | 22 | 75 | | } |
| | | 76 | | } |
| | | 77 | | |
| | | 78 | | public SecurityKeyEntropyMode KeyEntropyMode |
| | | 79 | | { |
| | | 80 | | get |
| | | 81 | | { |
| | 10 | 82 | | return _keyEntropyMode; |
| | | 83 | | } |
| | | 84 | | set |
| | | 85 | | { |
| | 22 | 86 | | CommunicationObject.ThrowIfDisposedOrImmutable(); |
| | 22 | 87 | | SecurityKeyEntropyModeHelper.Validate(value); |
| | 22 | 88 | | _keyEntropyMode = value; |
| | 22 | 89 | | } |
| | | 90 | | } |
| | | 91 | | |
| | | 92 | | public bool IsClientAnonymous |
| | | 93 | | { |
| | | 94 | | get |
| | | 95 | | { |
| | 0 | 96 | | return _isClientAnonymous; |
| | | 97 | | } |
| | | 98 | | set |
| | | 99 | | { |
| | 0 | 100 | | CommunicationObject.ThrowIfDisposedOrImmutable(); |
| | 0 | 101 | | _isClientAnonymous = value; |
| | 0 | 102 | | } |
| | | 103 | | } |
| | | 104 | | |
| | | 105 | | public TimeSpan SessionTokenLifetime |
| | | 106 | | { |
| | | 107 | | get |
| | | 108 | | { |
| | 0 | 109 | | return _sessionTokenLifetime; |
| | | 110 | | } |
| | | 111 | | set |
| | | 112 | | { |
| | 22 | 113 | | CommunicationObject.ThrowIfDisposedOrImmutable(); |
| | 22 | 114 | | if (value <= TimeSpan.Zero) |
| | | 115 | | { |
| | 0 | 116 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(val |
| | | 117 | | } |
| | | 118 | | |
| | 22 | 119 | | if (TimeoutHelper.IsTooLarge(value)) |
| | | 120 | | { |
| | 0 | 121 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(val |
| | 0 | 122 | | SRCommon.SFxTimeoutOutOfRangeTooBig)); |
| | | 123 | | } |
| | 22 | 124 | | _sessionTokenLifetime = value; |
| | 22 | 125 | | } |
| | | 126 | | } |
| | | 127 | | |
| | | 128 | | public TimeSpan KeyRenewalInterval |
| | | 129 | | { |
| | | 130 | | get |
| | | 131 | | { |
| | 0 | 132 | | return _keyRenewalInterval; |
| | | 133 | | } |
| | | 134 | | set |
| | | 135 | | { |
| | 22 | 136 | | CommunicationObject.ThrowIfDisposedOrImmutable(); |
| | 22 | 137 | | if (value <= TimeSpan.Zero) |
| | | 138 | | { |
| | 0 | 139 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(val |
| | | 140 | | } |
| | | 141 | | |
| | 22 | 142 | | if (TimeoutHelper.IsTooLarge(value)) |
| | | 143 | | { |
| | 0 | 144 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(val |
| | 0 | 145 | | SRCommon.SFxTimeoutOutOfRangeTooBig)); |
| | | 146 | | } |
| | 22 | 147 | | _keyRenewalInterval = value; |
| | 22 | 148 | | } |
| | | 149 | | } |
| | | 150 | | |
| | | 151 | | public int MaximumConcurrentNegotiations |
| | | 152 | | { |
| | | 153 | | get |
| | | 154 | | { |
| | 0 | 155 | | return _maximumConcurrentNegotiations; |
| | | 156 | | } |
| | | 157 | | set |
| | | 158 | | { |
| | 22 | 159 | | CommunicationObject.ThrowIfDisposedOrImmutable(); |
| | 22 | 160 | | if (value < 0) |
| | | 161 | | { |
| | 0 | 162 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(val |
| | | 163 | | } |
| | 22 | 164 | | _maximumConcurrentNegotiations = value; |
| | 22 | 165 | | } |
| | | 166 | | } |
| | | 167 | | |
| | | 168 | | public TimeSpan NegotiationTimeout |
| | | 169 | | { |
| | | 170 | | get |
| | | 171 | | { |
| | 22 | 172 | | return _negotiationTimeout; |
| | | 173 | | } |
| | | 174 | | set |
| | | 175 | | { |
| | 22 | 176 | | CommunicationObject.ThrowIfDisposedOrImmutable(); |
| | 22 | 177 | | if (value <= TimeSpan.Zero) |
| | | 178 | | { |
| | 0 | 179 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(val |
| | | 180 | | } |
| | 22 | 181 | | _negotiationTimeout = value; |
| | 22 | 182 | | } |
| | | 183 | | } |
| | | 184 | | |
| | 22 | 185 | | public SecurityContextSecurityTokenAuthenticator SessionTokenAuthenticator { get; } |
| | | 186 | | |
| | | 187 | | public ISecurityContextSecurityTokenCache IssuedTokenCache |
| | | 188 | | { |
| | | 189 | | get |
| | | 190 | | { |
| | 44 | 191 | | return _issuedTokenCache; |
| | | 192 | | } |
| | | 193 | | set |
| | | 194 | | { |
| | 22 | 195 | | CommunicationObject.ThrowIfDisposedOrImmutable(); |
| | 22 | 196 | | _issuedTokenCache = value; |
| | 22 | 197 | | } |
| | | 198 | | } |
| | | 199 | | |
| | | 200 | | public SecurityStandardsManager StandardsManager |
| | | 201 | | { |
| | | 202 | | get |
| | | 203 | | { |
| | 56 | 204 | | return _standardsManager; |
| | | 205 | | } |
| | | 206 | | set |
| | | 207 | | { |
| | 22 | 208 | | CommunicationObject.ThrowIfDisposedOrImmutable(); |
| | 22 | 209 | | if (value == null) |
| | | 210 | | { |
| | 0 | 211 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(value))); |
| | | 212 | | } |
| | 22 | 213 | | if (!value.TrustDriver.IsSessionSupported) |
| | | 214 | | { |
| | 0 | 215 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.TrustDriverVersio |
| | | 216 | | } |
| | 22 | 217 | | if (!value.SecureConversationDriver.IsSessionSupported) |
| | | 218 | | { |
| | 0 | 219 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.SecureConversatio |
| | | 220 | | } |
| | 22 | 221 | | _standardsManager = value; |
| | 22 | 222 | | } |
| | | 223 | | } |
| | | 224 | | |
| | | 225 | | public SecurityTokenParameters IssuedSecurityTokenParameters |
| | | 226 | | { |
| | | 227 | | get |
| | | 228 | | { |
| | 64 | 229 | | return _issuedTokenParameters; |
| | | 230 | | } |
| | | 231 | | set |
| | | 232 | | { |
| | 22 | 233 | | CommunicationObject.ThrowIfDisposedOrImmutable(); |
| | 22 | 234 | | _issuedTokenParameters = value; |
| | 22 | 235 | | } |
| | | 236 | | } |
| | | 237 | | |
| | | 238 | | public BindingContext IssuerBindingContext |
| | | 239 | | { |
| | | 240 | | get |
| | | 241 | | { |
| | 242 | 242 | | return _issuerBindingContext; |
| | | 243 | | } |
| | | 244 | | set |
| | | 245 | | { |
| | 22 | 246 | | CommunicationObject.ThrowIfDisposedOrImmutable(); |
| | 22 | 247 | | if (value == null) |
| | | 248 | | { |
| | 0 | 249 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(value)); |
| | | 250 | | } |
| | 22 | 251 | | _issuerBindingContext = value.Clone(); |
| | 22 | 252 | | } |
| | | 253 | | } |
| | | 254 | | |
| | | 255 | | public SecurityBindingElement BootstrapSecurityBindingElement |
| | | 256 | | { |
| | 22 | 257 | | get { return _bootstrapSecurityBindingElement; } |
| | | 258 | | set |
| | | 259 | | { |
| | 22 | 260 | | CommunicationObject.ThrowIfDisposedOrImmutable(); |
| | 22 | 261 | | if (value == null) |
| | | 262 | | { |
| | 0 | 263 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(value)); |
| | | 264 | | } |
| | 22 | 265 | | _bootstrapSecurityBindingElement = (SecurityBindingElement)value.Clone(); |
| | 22 | 266 | | } |
| | | 267 | | } |
| | | 268 | | |
| | | 269 | | public IMessageFilterTable<EndpointAddress> EndpointFilterTable |
| | | 270 | | { |
| | | 271 | | get |
| | | 272 | | { |
| | 0 | 273 | | return _endpointFilterTable; |
| | | 274 | | } |
| | | 275 | | set |
| | | 276 | | { |
| | 22 | 277 | | CommunicationObject.ThrowIfDisposedOrImmutable(); |
| | 22 | 278 | | _endpointFilterTable = value; |
| | 22 | 279 | | } |
| | | 280 | | } |
| | | 281 | | |
| | | 282 | | public Uri ListenUri |
| | | 283 | | { |
| | 22 | 284 | | get { return _listenUri; } |
| | | 285 | | set |
| | | 286 | | { |
| | 22 | 287 | | CommunicationObject.ThrowIfDisposedOrImmutable(); |
| | 22 | 288 | | _listenUri = value; |
| | 22 | 289 | | } |
| | | 290 | | } |
| | | 291 | | |
| | | 292 | | public virtual XmlDictionaryString IssueAction |
| | | 293 | | { |
| | | 294 | | get |
| | | 295 | | { |
| | 32 | 296 | | return _standardsManager.SecureConversationDriver.IssueAction; |
| | | 297 | | } |
| | | 298 | | } |
| | | 299 | | |
| | | 300 | | public virtual XmlDictionaryString IssueResponseAction |
| | | 301 | | { |
| | | 302 | | get |
| | | 303 | | { |
| | 10 | 304 | | return _standardsManager.SecureConversationDriver.IssueResponseAction; |
| | | 305 | | } |
| | | 306 | | } |
| | | 307 | | |
| | 32 | 308 | | public bool PreserveBootstrapTokens { get; set; } |
| | | 309 | | |
| | | 310 | | public virtual XmlDictionaryString RenewAction |
| | | 311 | | { |
| | | 312 | | get |
| | | 313 | | { |
| | 44 | 314 | | return _standardsManager.SecureConversationDriver.RenewAction; |
| | | 315 | | } |
| | | 316 | | } |
| | | 317 | | |
| | | 318 | | public virtual XmlDictionaryString RenewResponseAction |
| | | 319 | | { |
| | | 320 | | get |
| | | 321 | | { |
| | 0 | 322 | | return _standardsManager.SecureConversationDriver.RenewResponseAction; |
| | | 323 | | } |
| | | 324 | | } |
| | | 325 | | |
| | | 326 | | public virtual XmlDictionaryString CloseAction |
| | | 327 | | { |
| | | 328 | | get |
| | | 329 | | { |
| | 0 | 330 | | return _standardsManager.SecureConversationDriver.CloseAction; |
| | | 331 | | } |
| | | 332 | | } |
| | | 333 | | |
| | | 334 | | public virtual XmlDictionaryString CloseResponseAction |
| | | 335 | | { |
| | | 336 | | get |
| | | 337 | | { |
| | 0 | 338 | | return _standardsManager.SecureConversationDriver.CloseResponseAction; |
| | | 339 | | } |
| | | 340 | | } |
| | | 341 | | |
| | | 342 | | //public bool RemoveCachedLogonToken(string username) |
| | | 343 | | //{ |
| | | 344 | | // if (this.RequestSecurityTokenListener != null) |
| | | 345 | | // { |
| | | 346 | | // // |
| | | 347 | | // // this is the SCT case, delegate to the RST's listener list |
| | | 348 | | // // |
| | | 349 | | // IChannelListener listener = null; |
| | | 350 | | // ILogonTokenCacheManager manager = null; |
| | | 351 | | |
| | | 352 | | // for (int i = 0; i < this.RequestSecurityTokenListener.ChannelDispatchers.Count; i++) |
| | | 353 | | // { |
| | | 354 | | // listener = this.RequestSecurityTokenListener.ChannelDispatchers[i].Listener; |
| | | 355 | | |
| | | 356 | | // if (listener != null) |
| | | 357 | | // { |
| | | 358 | | // manager = listener.GetProperty<ILogonTokenCacheManager>(); |
| | | 359 | | |
| | | 360 | | // if (manager != null) |
| | | 361 | | // return manager.RemoveCachedLogonToken(username); |
| | | 362 | | // } |
| | | 363 | | // } |
| | | 364 | | // } |
| | | 365 | | // return false; |
| | | 366 | | //} |
| | | 367 | | |
| | | 368 | | //public void FlushLogonTokenCache() |
| | | 369 | | //{ |
| | | 370 | | // if (this.RequestSecurityTokenListener != null && this.RequestSecurityTokenListener.ChannelDispatchers.Coun |
| | | 371 | | // { |
| | | 372 | | // // |
| | | 373 | | // // this is the SCT case, delegate to the RST's listener list |
| | | 374 | | // // |
| | | 375 | | // IChannelListener listener = null; |
| | | 376 | | // ILogonTokenCacheManager manager = null; |
| | | 377 | | |
| | | 378 | | // for (int i = 0; i < this.RequestSecurityTokenListener.ChannelDispatchers.Count; i++) |
| | | 379 | | // { |
| | | 380 | | // listener = this.RequestSecurityTokenListener.ChannelDispatchers[i].Listener; |
| | | 381 | | |
| | | 382 | | // if (listener != null) |
| | | 383 | | // { |
| | | 384 | | // manager = listener.GetProperty<ILogonTokenCacheManager>(); |
| | | 385 | | |
| | | 386 | | // if (manager != null) |
| | | 387 | | // manager.FlushLogonTokenCache(); |
| | | 388 | | // } |
| | | 389 | | // } |
| | | 390 | | // } |
| | | 391 | | |
| | | 392 | | // } |
| | | 393 | | |
| | | 394 | | private Message HandleOperationException(SecuritySessionOperation operation, Message request, Exception e) |
| | | 395 | | { |
| | | 396 | | // SecurityTraceRecordHelper.TraceServerSessionOperationException(operation, e, this.ListenUri); |
| | 0 | 397 | | return CreateFault(request, e); |
| | | 398 | | } |
| | | 399 | | |
| | | 400 | | private Message CreateFault(Message request, Exception e) |
| | | 401 | | { |
| | | 402 | | FaultCode subCode; |
| | | 403 | | FaultReason reason; |
| | | 404 | | bool isSenderFault; |
| | 0 | 405 | | if (e is QuotaExceededException) |
| | | 406 | | { |
| | | 407 | | // send a receiver fault so that the sender can retry |
| | 0 | 408 | | subCode = new FaultCode(DotNetSecurityStrings.SecurityServerTooBusyFault, DotNetSecurityStrings.Namespac |
| | 0 | 409 | | reason = new FaultReason(SR.PendingSessionsExceededFaultReason, CultureInfo.CurrentCulture); |
| | 0 | 410 | | isSenderFault = false; |
| | | 411 | | } |
| | 0 | 412 | | else if (e is EndpointNotFoundException) |
| | | 413 | | { |
| | | 414 | | // send a receiver fault so that the sender can retry |
| | 0 | 415 | | subCode = new FaultCode(AddressingStrings.EndpointUnavailable, request.Version.Addressing.Namespace); |
| | 0 | 416 | | reason = new FaultReason(SR.SecurityListenerClosingFaultReason, CultureInfo.CurrentCulture); |
| | 0 | 417 | | isSenderFault = false; |
| | | 418 | | } |
| | | 419 | | else |
| | | 420 | | { |
| | 0 | 421 | | subCode = new FaultCode(TrustApr2004Strings.InvalidRequestFaultCode, TrustFeb2005Strings.Namespace); |
| | 0 | 422 | | reason = new FaultReason(SR.InvalidRequestTrustFaultCode, CultureInfo.CurrentCulture); |
| | 0 | 423 | | isSenderFault = true; |
| | | 424 | | } |
| | | 425 | | FaultCode faultCode; |
| | 0 | 426 | | if (isSenderFault) |
| | | 427 | | { |
| | 0 | 428 | | faultCode = FaultCode.CreateSenderFaultCode(subCode); |
| | | 429 | | } |
| | | 430 | | else |
| | | 431 | | { |
| | 0 | 432 | | faultCode = FaultCode.CreateReceiverFaultCode(subCode); |
| | | 433 | | } |
| | 0 | 434 | | MessageFault fault = MessageFault.CreateFault(faultCode, reason); |
| | 0 | 435 | | Message faultReply = Message.CreateMessage(request.Version, fault, request.Version.Addressing.DefaultFaultAc |
| | 0 | 436 | | faultReply.Headers.RelatesTo = request.Headers.MessageId; |
| | 0 | 437 | | return faultReply; |
| | | 438 | | } |
| | | 439 | | |
| | | 440 | | private void NotifyOperationCompletion(SecuritySessionOperation operation, SecurityContextSecurityToken newSessi |
| | | 441 | | { |
| | 10 | 442 | | if (operation == SecuritySessionOperation.Issue) |
| | | 443 | | { |
| | 10 | 444 | | if (IssuedSecurityTokenHandler != null) |
| | | 445 | | { |
| | 10 | 446 | | IssuedSecurityTokenHandler(newSessionToken, remoteAddress); |
| | | 447 | | } |
| | | 448 | | else |
| | | 449 | | { |
| | 0 | 450 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new SecurityNegotiationException(SR.Issu |
| | | 451 | | } |
| | | 452 | | } |
| | 0 | 453 | | else if (operation == SecuritySessionOperation.Renew) |
| | | 454 | | { |
| | 0 | 455 | | if (RenewedSecurityTokenHandler != null) |
| | | 456 | | { |
| | 0 | 457 | | RenewedSecurityTokenHandler(newSessionToken, previousSessionToken); |
| | | 458 | | } |
| | | 459 | | else |
| | | 460 | | { |
| | 0 | 461 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new SecurityNegotiationException(SR.Rene |
| | | 462 | | } |
| | | 463 | | } |
| | | 464 | | else |
| | | 465 | | { |
| | 0 | 466 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); |
| | | 467 | | } |
| | | 468 | | } |
| | | 469 | | |
| | | 470 | | public override Task CloseAsync(CancellationToken token) |
| | | 471 | | { |
| | | 472 | | /* TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); |
| | | 473 | | if (this.rstListener != null) |
| | | 474 | | { |
| | | 475 | | this.rstListener.Close(timeoutHelper.RemainingTime()); |
| | | 476 | | this.rstListener = null; |
| | | 477 | | }*/ |
| | | 478 | | |
| | 0 | 479 | | return base.CloseAsync(token); |
| | | 480 | | } |
| | | 481 | | |
| | | 482 | | public override Task OpenAsync(CancellationToken token) |
| | | 483 | | { |
| | 22 | 484 | | if (BootstrapSecurityBindingElement == null) |
| | | 485 | | { |
| | 0 | 486 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.Boo |
| | | 487 | | } |
| | 22 | 488 | | if (IssuerBindingContext == null) |
| | | 489 | | { |
| | 0 | 490 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.Iss |
| | | 491 | | } |
| | 22 | 492 | | if (IssuedSecurityTokenParameters == null) |
| | | 493 | | { |
| | 0 | 494 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.Iss |
| | | 495 | | } |
| | 22 | 496 | | if (SecurityAlgorithmSuite == null) |
| | | 497 | | { |
| | 0 | 498 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.Sec |
| | | 499 | | } |
| | 22 | 500 | | if (IssuedTokenCache == null) |
| | | 501 | | { |
| | 0 | 502 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.Iss |
| | | 503 | | } |
| | | 504 | | //TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); |
| | 22 | 505 | | SetupSessionListener(); |
| | 22 | 506 | | ChannelDispatcher channelDispatcher = RequestSecurityTokenListener.InitializeRuntime(SecurityServiceDispatch |
| | 22 | 507 | | SecurityServiceDispatcher.SecurityAuthServiceDispatcher = new ServiceDispatcher(channelDispatcher); |
| | 22 | 508 | | _sctUri = StandardsManager.SecureConversationDriver.TokenTypeUri; |
| | 22 | 509 | | return base.OpenAsync(); |
| | | 510 | | // base.OnOpen(timeoutHelper.RemainingTime()); |
| | | 511 | | } |
| | | 512 | | |
| | | 513 | | protected override bool CanValidateTokenCore(SecurityToken token) |
| | | 514 | | { |
| | 40 | 515 | | return (token is SecurityContextSecurityToken); |
| | | 516 | | } |
| | | 517 | | |
| | | 518 | | protected override ValueTask<ReadOnlyCollection<IAuthorizationPolicy>> ValidateTokenCoreAsync(SecurityToken toke |
| | | 519 | | { |
| | 20 | 520 | | SecurityContextSecurityToken sct = (SecurityContextSecurityToken)token; |
| | 20 | 521 | | return new ValueTask<ReadOnlyCollection<IAuthorizationPolicy>>(sct.AuthorizationPolicies); |
| | | 522 | | } |
| | | 523 | | |
| | | 524 | | private static bool IsSameIdentity(ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies, ServiceSecuri |
| | | 525 | | { |
| | 0 | 526 | | Claim identityClaim = SecurityUtils.GetPrimaryIdentityClaim(authorizationPolicies); |
| | | 527 | | |
| | 0 | 528 | | if (identityClaim == null) |
| | | 529 | | { |
| | 0 | 530 | | return incomingContext.IsAnonymous; |
| | | 531 | | } |
| | | 532 | | else |
| | | 533 | | { |
| | 0 | 534 | | return Claim.DefaultComparer.Equals(incomingContext.IdentityClaim, identityClaim); |
| | | 535 | | } |
| | | 536 | | } |
| | | 537 | | |
| | | 538 | | private DateTime GetKeyExpirationTime(SecurityToken currentToken, DateTime keyEffectiveTime) |
| | | 539 | | { |
| | 10 | 540 | | DateTime keyExpirationTime = TimeoutHelper.Add(keyEffectiveTime, _keyRenewalInterval); |
| | 10 | 541 | | DateTime tokenExpirationTime = (currentToken != null) ? currentToken.ValidTo : TimeoutHelper.Add(keyEffectiv |
| | 10 | 542 | | if (keyExpirationTime > tokenExpirationTime) |
| | | 543 | | { |
| | 0 | 544 | | keyExpirationTime = tokenExpirationTime; |
| | | 545 | | } |
| | 10 | 546 | | return keyExpirationTime; |
| | | 547 | | } |
| | | 548 | | |
| | | 549 | | internal static ReadOnlyCollection<IAuthorizationPolicy> CreateSecureConversationPolicies(SecurityMessagePropert |
| | | 550 | | { |
| | 0 | 551 | | return CreateSecureConversationPolicies(security, null, expirationTime); |
| | | 552 | | } |
| | | 553 | | |
| | | 554 | | private static ReadOnlyCollection<IAuthorizationPolicy> CreateSecureConversationPolicies(SecurityMessageProperty |
| | | 555 | | { |
| | 10 | 556 | | if (security == null) |
| | | 557 | | { |
| | 0 | 558 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(security)); |
| | | 559 | | } |
| | | 560 | | |
| | 10 | 561 | | List<IAuthorizationPolicy> authorizationPolicies = new List<IAuthorizationPolicy>(); |
| | 10 | 562 | | if ((security.ServiceSecurityContext != null) && |
| | 10 | 563 | | (security.ServiceSecurityContext.AuthorizationPolicies != null)) |
| | | 564 | | { |
| | 10 | 565 | | authorizationPolicies.AddRange(security.ServiceSecurityContext.AuthorizationPolicies); |
| | | 566 | | |
| | | 567 | | // Remove any Transport token policies. We do not include |
| | | 568 | | // these in the SCT as these policies will be available with |
| | | 569 | | // the application messages as well. |
| | 10 | 570 | | if ((security.TransportToken != null) && |
| | 10 | 571 | | (security.TransportToken.SecurityTokenPolicies != null) && |
| | 10 | 572 | | (security.TransportToken.SecurityTokenPolicies.Count > 0)) |
| | | 573 | | { |
| | 0 | 574 | | foreach (IAuthorizationPolicy policy in security.TransportToken.SecurityTokenPolicies) |
| | | 575 | | { |
| | 0 | 576 | | if (authorizationPolicies.Contains(policy)) |
| | | 577 | | { |
| | 0 | 578 | | authorizationPolicies.Remove(policy); |
| | | 579 | | } |
| | | 580 | | } |
| | | 581 | | } |
| | | 582 | | |
| | 10 | 583 | | if (currentTokenPolicies != null) |
| | | 584 | | { |
| | 0 | 585 | | for (int i = 0; i < currentTokenPolicies.Count; ++i) |
| | | 586 | | { |
| | 0 | 587 | | if (authorizationPolicies.Contains(currentTokenPolicies[i])) |
| | | 588 | | { |
| | 0 | 589 | | authorizationPolicies.Remove(currentTokenPolicies[i]); |
| | | 590 | | } |
| | | 591 | | } |
| | | 592 | | } |
| | | 593 | | |
| | | 594 | | UnconditionalPolicy sctPolicy; |
| | 44 | 595 | | for (int i = 0; i < authorizationPolicies.Count; i++) |
| | | 596 | | { |
| | 12 | 597 | | if (authorizationPolicies[i].GetType() == typeof(UnconditionalPolicy)) |
| | | 598 | | { |
| | 10 | 599 | | UnconditionalPolicy bootstrapPolicy = (UnconditionalPolicy)authorizationPolicies[i]; |
| | 10 | 600 | | sctPolicy = new UnconditionalPolicy(bootstrapPolicy.PrimaryIdentity, bootstrapPolicy.Issuances, |
| | 10 | 601 | | authorizationPolicies[i] = sctPolicy; |
| | | 602 | | } |
| | | 603 | | } |
| | | 604 | | } |
| | | 605 | | |
| | 10 | 606 | | return authorizationPolicies.AsReadOnly(); |
| | | 607 | | } |
| | | 608 | | |
| | | 609 | | private SecurityContextSecurityToken IssueToken(RequestSecurityToken rst, Message request, SecurityContextSecuri |
| | | 610 | | { |
| | 10 | 611 | | if (rst.TokenType != null && rst.TokenType != _sctUri) |
| | | 612 | | { |
| | 0 | 613 | | throw TraceUtility.ThrowHelperWarning(new InvalidOperationException(SR.Format(SR.CannotIssueRstTokenType |
| | | 614 | | } |
| | | 615 | | // ensure that a SecurityContext is present in the message |
| | | 616 | | ServiceSecurityContext clientContext; |
| | 10 | 617 | | SecurityMessageProperty securityProperty = request.Properties.Security; |
| | 10 | 618 | | if (securityProperty != null) |
| | | 619 | | { |
| | 10 | 620 | | clientContext = securityProperty.ServiceSecurityContext; |
| | | 621 | | } |
| | | 622 | | else |
| | | 623 | | { |
| | 0 | 624 | | clientContext = ServiceSecurityContext.Anonymous; |
| | | 625 | | } |
| | 10 | 626 | | if (clientContext == null) |
| | | 627 | | { |
| | 0 | 628 | | throw TraceUtility.ThrowHelperWarning(new InvalidOperationException(SR.Format(SR.SecurityContextMissing, |
| | | 629 | | } |
| | 10 | 630 | | if (currentToken != null) |
| | | 631 | | { |
| | | 632 | | // ensure that the same party is renewing the token |
| | 0 | 633 | | if (!IsSameIdentity(currentToken.AuthorizationPolicies, clientContext)) |
| | | 634 | | { |
| | 0 | 635 | | throw TraceUtility.ThrowHelperWarning(new SecurityNegotiationException(SR.WrongIdentityRenewingToken |
| | | 636 | | } |
| | | 637 | | } |
| | | 638 | | |
| | | 639 | | // check if the client specified entropy |
| | 10 | 640 | | WSTrust.Driver.ProcessRstAndIssueKey(rst, null, KeyEntropyMode, SecurityAlgorithmSuite, out int issuedKeySiz |
| | 10 | 641 | | out byte[] issuerEntropy, out byte[] proofKey, out SecurityToken proofToken); |
| | | 642 | | SecurityContextSecurityToken newToken; |
| | 10 | 643 | | DateTime keyEffectiveTime = DateTime.UtcNow; |
| | 10 | 644 | | DateTime keyExpirationTime = GetKeyExpirationTime(currentToken, keyEffectiveTime); |
| | 10 | 645 | | ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies = (securityProperty != null) ? |
| | 10 | 646 | | CreateSecureConversationPolicies(securityProperty, currentTokenPolicies, keyExpirationTime) : EmptyR |
| | 10 | 647 | | if (currentToken != null) |
| | | 648 | | { |
| | 0 | 649 | | newToken = new SecurityContextSecurityToken(currentToken, SecurityUtils.GenerateId(), proofKey, |
| | 0 | 650 | | SecurityUtils.GenerateUniqueId(), keyEffectiveTime, keyExpirationTime, authorizationPolicies); |
| | | 651 | | } |
| | | 652 | | else |
| | | 653 | | { |
| | 10 | 654 | | UniqueId contextId = SecurityUtils.GenerateUniqueId(); |
| | 10 | 655 | | string id = SecurityUtils.GenerateId(); |
| | 10 | 656 | | DateTime tokenEffectiveTime = keyEffectiveTime; |
| | 10 | 657 | | DateTime tokenExpirationTime = TimeoutHelper.Add(tokenEffectiveTime, _sessionTokenLifetime); |
| | 10 | 658 | | newToken = new SecurityContextSecurityToken(contextId, id, proofKey, tokenEffectiveTime, tokenExpiration |
| | 10 | 659 | | keyExpirationTime, authorizationPolicies); |
| | 10 | 660 | | if (PreserveBootstrapTokens) |
| | | 661 | | { |
| | 0 | 662 | | newToken.BootstrapMessageProperty = (securityProperty == null) ? null : (SecurityMessageProperty)sec |
| | 0 | 663 | | SecurityUtils.ErasePasswordInUsernameTokenIfPresent(newToken.BootstrapMessageProperty); |
| | | 664 | | } |
| | | 665 | | } |
| | | 666 | | |
| | 10 | 667 | | rstr = new RequestSecurityTokenResponse(_standardsManager) |
| | 10 | 668 | | { |
| | 10 | 669 | | Context = rst.Context, |
| | 10 | 670 | | KeySize = issuedKeySize, |
| | 10 | 671 | | RequestedUnattachedReference = IssuedSecurityTokenParameters.CreateKeyIdentifierClause(newToken, Securit |
| | 10 | 672 | | RequestedAttachedReference = IssuedSecurityTokenParameters.CreateKeyIdentifierClause(newToken, SecurityT |
| | 10 | 673 | | TokenType = _sctUri, |
| | 10 | 674 | | RequestedSecurityToken = newToken |
| | 10 | 675 | | }; |
| | 10 | 676 | | if (issuerEntropy != null) |
| | | 677 | | { |
| | 10 | 678 | | rstr.SetIssuerEntropy(issuerEntropy); |
| | 10 | 679 | | rstr.ComputeKey = true; |
| | | 680 | | } |
| | 10 | 681 | | if (proofToken != null) |
| | | 682 | | { |
| | 0 | 683 | | rstr.RequestedProofToken = proofToken; |
| | | 684 | | } |
| | 10 | 685 | | rstr.SetLifetime(keyEffectiveTime, keyExpirationTime); |
| | 10 | 686 | | return newToken; |
| | | 687 | | } |
| | | 688 | | |
| | | 689 | | private static SecurityTokenSpecification GetMatchingEndorsingSct(SecurityContextKeyIdentifierClause sctSkiClaus |
| | | 690 | | { |
| | 0 | 691 | | if (sctSkiClause == null) |
| | | 692 | | { |
| | 0 | 693 | | return null; |
| | | 694 | | } |
| | 0 | 695 | | for (int i = 0; i < supportingTokenProperty.IncomingSupportingTokens.Count; ++i) |
| | | 696 | | { |
| | 0 | 697 | | if (supportingTokenProperty.IncomingSupportingTokens[i].SecurityTokenAttachmentMode != SecurityTokenAtta |
| | 0 | 698 | | && supportingTokenProperty.IncomingSupportingTokens[i].SecurityTokenAttachmentMode != SecurityTokenA |
| | | 699 | | { |
| | | 700 | | continue; |
| | | 701 | | } |
| | 0 | 702 | | if (supportingTokenProperty.IncomingSupportingTokens[i].SecurityToken is SecurityContextSecurityToken sc |
| | | 703 | | { |
| | 0 | 704 | | return supportingTokenProperty.IncomingSupportingTokens[i]; |
| | | 705 | | } |
| | | 706 | | } |
| | 0 | 707 | | return null; |
| | | 708 | | } |
| | | 709 | | |
| | | 710 | | |
| | | 711 | | protected virtual Message ProcessRenewRequest(Message request) |
| | | 712 | | { |
| | 0 | 713 | | CommunicationObject.ThrowIfClosedOrNotOpen(); |
| | | 714 | | try |
| | | 715 | | { |
| | | 716 | | // first verify that the session token being renewed is present as a supportingToken |
| | 0 | 717 | | SecurityMessageProperty supportingTokenProperty = request.Properties.Security; |
| | 0 | 718 | | if (supportingTokenProperty == null || !supportingTokenProperty.HasIncomingSupportingTokens) |
| | | 719 | | { |
| | 0 | 720 | | throw TraceUtility.ThrowHelperWarning(new SecurityNegotiationException(SR.RenewSessionMissingSupport |
| | | 721 | | } |
| | | 722 | | |
| | | 723 | | RequestSecurityToken rst; |
| | 0 | 724 | | XmlDictionaryReader bodyReader = request.GetReaderAtBodyContents(); |
| | 0 | 725 | | using (bodyReader) |
| | | 726 | | { |
| | 0 | 727 | | rst = StandardsManager.TrustDriver.CreateRequestSecurityToken(bodyReader); |
| | 0 | 728 | | request.ReadFromBodyContentsToEnd(bodyReader); |
| | 0 | 729 | | } |
| | 0 | 730 | | if (rst.RequestType != StandardsManager.TrustDriver.RequestTypeRenew) |
| | | 731 | | { |
| | 0 | 732 | | throw TraceUtility.ThrowHelperWarning(new SecurityNegotiationException(SR.Format(SR.InvalidRstReques |
| | | 733 | | } |
| | 0 | 734 | | if (rst.RenewTarget == null) |
| | | 735 | | { |
| | 0 | 736 | | throw TraceUtility.ThrowHelperWarning(new SecurityNegotiationException(SR.NoRenewTargetSpecified), r |
| | | 737 | | } |
| | 0 | 738 | | SecurityContextKeyIdentifierClause sctSkiClause = rst.RenewTarget as SecurityContextKeyIdentifierClause; |
| | 0 | 739 | | SecurityTokenSpecification sessionToken = GetMatchingEndorsingSct(sctSkiClause, supportingTokenProperty) |
| | 0 | 740 | | if (sctSkiClause == null || sessionToken == null) |
| | | 741 | | { |
| | 0 | 742 | | throw TraceUtility.ThrowHelperWarning(new SecurityNegotiationException(SR.Format(SR.BadRenewTarget, |
| | | 743 | | } |
| | 0 | 744 | | SecurityContextSecurityToken newToken = IssueToken(rst, request, (SecurityContextSecurityToken)sessionTo |
| | 0 | 745 | | rstr.MakeReadOnly(); |
| | 0 | 746 | | BodyWriter replyMessage = rstr; |
| | 0 | 747 | | if (StandardsManager.MessageSecurityVersion.TrustVersion == TrustVersion.WSTrust13) |
| | | 748 | | { |
| | 0 | 749 | | List<RequestSecurityTokenResponse> rstrList = new List<RequestSecurityTokenResponse>(1) |
| | 0 | 750 | | { |
| | 0 | 751 | | rstr |
| | 0 | 752 | | }; |
| | 0 | 753 | | RequestSecurityTokenResponseCollection rstrc = new RequestSecurityTokenResponseCollection(rstrList, |
| | 0 | 754 | | replyMessage = rstrc; |
| | | 755 | | } |
| | 0 | 756 | | NotifyOperationCompletion(SecuritySessionOperation.Renew, newToken, (SecurityContextSecurityToken)sessio |
| | 0 | 757 | | Message response = CreateReply(request, RenewResponseAction, replyMessage); |
| | | 758 | | |
| | 0 | 759 | | if (!newToken.IsCookieMode) |
| | | 760 | | { |
| | 0 | 761 | | _issuedTokenCache.AddContext(newToken); |
| | | 762 | | } |
| | 0 | 763 | | return response; |
| | | 764 | | } |
| | | 765 | | finally |
| | | 766 | | { |
| | 0 | 767 | | RemoveCachedTokensIfRequired(request.Properties.Security); |
| | 0 | 768 | | } |
| | 0 | 769 | | } |
| | | 770 | | |
| | | 771 | | private static void AddTokenToRemoveIfRequired(SecurityToken token, Collection<SecurityContextSecurityToken> sct |
| | | 772 | | { |
| | 10 | 773 | | if (token is SecurityContextSecurityToken sct) |
| | | 774 | | { |
| | 0 | 775 | | sctsToRemove.Add(sct); |
| | | 776 | | } |
| | 10 | 777 | | } |
| | | 778 | | |
| | | 779 | | internal static void RemoveCachedTokensIfRequired(SecurityMessageProperty security) |
| | | 780 | | { |
| | 10 | 781 | | if (security == null) |
| | | 782 | | { |
| | 0 | 783 | | return; |
| | | 784 | | } |
| | | 785 | | // ILogonTokenCacheManager logonManager = OperationContext.Current.EndpointDispatcher.ChannelDispatcher.List |
| | | 786 | | |
| | | 787 | | // Collection<ISecurityContextSecurityTokenCache> sctCaches = OperationContext.Current.EndpointDispatcher.Ch |
| | | 788 | | // if ( (sctCaches == null || sctCaches.Count == 0)) |
| | | 789 | | // { |
| | | 790 | | // return; |
| | | 791 | | // } |
| | | 792 | | //TODO debug and incorporate above logic |
| | 10 | 793 | | Collection<ISecurityContextSecurityTokenCache> sctCaches = new Collection<ISecurityContextSecurityTokenCache |
| | 10 | 794 | | Collection<SecurityContextSecurityToken> securityContextTokensToRemove = new Collection<SecurityContextSecur |
| | 10 | 795 | | if (security.ProtectionToken != null) |
| | | 796 | | { |
| | 0 | 797 | | AddTokenToRemoveIfRequired(security.ProtectionToken.SecurityToken, securityContextTokensToRemove); |
| | | 798 | | } |
| | 10 | 799 | | if (security.InitiatorToken != null) |
| | | 800 | | { |
| | 0 | 801 | | AddTokenToRemoveIfRequired(security.InitiatorToken.SecurityToken, securityContextTokensToRemove); |
| | | 802 | | } |
| | 10 | 803 | | if (security.HasIncomingSupportingTokens) |
| | | 804 | | { |
| | 40 | 805 | | for (int i = 0; i < security.IncomingSupportingTokens.Count; ++i) |
| | | 806 | | { |
| | 10 | 807 | | if (security.IncomingSupportingTokens[i].SecurityTokenAttachmentMode == SecurityTokenAttachmentMode. |
| | 10 | 808 | | || security.IncomingSupportingTokens[i].SecurityTokenAttachmentMode == SecurityTokenAttachmentMo |
| | 10 | 809 | | || security.IncomingSupportingTokens[i].SecurityTokenAttachmentMode == SecurityTokenAttachmentMo |
| | | 810 | | { |
| | 10 | 811 | | AddTokenToRemoveIfRequired(security.IncomingSupportingTokens[i].SecurityToken, securityContextTo |
| | | 812 | | } |
| | | 813 | | } |
| | | 814 | | } |
| | 10 | 815 | | if (sctCaches != null) |
| | | 816 | | { |
| | 20 | 817 | | for (int i = 0; i < securityContextTokensToRemove.Count; ++i) |
| | | 818 | | { |
| | 0 | 819 | | for (int j = 0; j < sctCaches.Count; ++j) |
| | | 820 | | { |
| | 0 | 821 | | sctCaches[j].RemoveContext(securityContextTokensToRemove[i].ContextId, securityContextTokensToRe |
| | | 822 | | } |
| | | 823 | | } |
| | | 824 | | } |
| | 10 | 825 | | } |
| | | 826 | | |
| | | 827 | | protected virtual Message ProcessIssueRequest(Message request) |
| | | 828 | | { |
| | | 829 | | try |
| | | 830 | | { |
| | | 831 | | RequestSecurityToken rst; |
| | 10 | 832 | | using (XmlDictionaryReader bodyReader = request.GetReaderAtBodyContents()) |
| | | 833 | | { |
| | 10 | 834 | | rst = StandardsManager.TrustDriver.CreateRequestSecurityToken(bodyReader); |
| | 10 | 835 | | request.ReadFromBodyContentsToEnd(bodyReader); |
| | 10 | 836 | | } |
| | 10 | 837 | | if (rst.RequestType != null && rst.RequestType != StandardsManager.TrustDriver.RequestTypeIssue) |
| | | 838 | | { |
| | 0 | 839 | | throw TraceUtility.ThrowHelperWarning(new SecurityNegotiationException(SR.Format(SR.InvalidRstReques |
| | | 840 | | } |
| | | 841 | | // echo the AppliesTo in the reply if it is an issue request |
| | 10 | 842 | | EndpointAddress appliesTo = null; |
| | | 843 | | DataContractSerializer appliesToSerializer; |
| | 10 | 844 | | rst.GetAppliesToQName(out string appliesToName, out string appliesToNamespace); |
| | 10 | 845 | | if (appliesToName == AddressingStrings.EndpointReference && appliesToNamespace == request.Version.Addres |
| | | 846 | | { |
| | 0 | 847 | | if (request.Version.Addressing == AddressingVersion.WSAddressing10) |
| | | 848 | | { |
| | 0 | 849 | | appliesToSerializer = DataContractSerializerDefaults.CreateSerializer(typeof(EndpointAddress10), |
| | 0 | 850 | | appliesTo = rst.GetAppliesTo<EndpointAddress10>(appliesToSerializer).ToEndpointAddress(); |
| | | 851 | | } |
| | 0 | 852 | | else if (request.Version.Addressing == AddressingVersion.WSAddressingAugust2004) |
| | | 853 | | { |
| | 0 | 854 | | appliesToSerializer = DataContractSerializerDefaults.CreateSerializer(typeof(EndpointAddressAugu |
| | 0 | 855 | | appliesTo = rst.GetAppliesTo<EndpointAddressAugust2004>(appliesToSerializer).ToEndpointAddress() |
| | | 856 | | } |
| | | 857 | | else |
| | | 858 | | { |
| | 0 | 859 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( |
| | 0 | 860 | | new ProtocolException(SR.Format(SR.AddressingVersionNotSupported, request.Version.Addressing |
| | | 861 | | } |
| | | 862 | | } |
| | | 863 | | else |
| | | 864 | | { |
| | 10 | 865 | | appliesTo = null; |
| | 10 | 866 | | appliesToSerializer = null; |
| | | 867 | | } |
| | 10 | 868 | | if (_shouldMatchRstWithEndpointFilter) |
| | | 869 | | { |
| | 2 | 870 | | SecurityUtils.MatchRstWithEndpointFilter(request, _endpointFilterTable, _listenUri); |
| | | 871 | | } |
| | 10 | 872 | | SecurityContextSecurityToken issuedToken = IssueToken(rst, request, null, null, out RequestSecurityToken |
| | 10 | 873 | | if (appliesTo != null) |
| | | 874 | | { |
| | 0 | 875 | | if (request.Version.Addressing == AddressingVersion.WSAddressing10) |
| | | 876 | | { |
| | 0 | 877 | | rstr.SetAppliesTo<EndpointAddress10>(EndpointAddress10.FromEndpointAddress(appliesTo), appliesTo |
| | | 878 | | } |
| | 0 | 879 | | else if (request.Version.Addressing == AddressingVersion.WSAddressingAugust2004) |
| | | 880 | | { |
| | 0 | 881 | | rstr.SetAppliesTo<EndpointAddressAugust2004>(EndpointAddressAugust2004.FromEndpointAddress(appli |
| | | 882 | | } |
| | | 883 | | else |
| | | 884 | | { |
| | 0 | 885 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( |
| | 0 | 886 | | new ProtocolException(SR.Format(SR.AddressingVersionNotSupported, request.Version.Addressing |
| | | 887 | | } |
| | | 888 | | } |
| | 10 | 889 | | rstr.MakeReadOnly(); |
| | 10 | 890 | | BodyWriter replyMessage = rstr; |
| | 10 | 891 | | if (StandardsManager.MessageSecurityVersion.TrustVersion == TrustVersion.WSTrust13) |
| | | 892 | | { |
| | 4 | 893 | | List<RequestSecurityTokenResponse> rstrList = new List<RequestSecurityTokenResponse>(1) |
| | 4 | 894 | | { |
| | 4 | 895 | | rstr |
| | 4 | 896 | | }; |
| | 4 | 897 | | RequestSecurityTokenResponseCollection rstrc = new RequestSecurityTokenResponseCollection(rstrList, |
| | 4 | 898 | | replyMessage = rstrc; |
| | | 899 | | } |
| | 10 | 900 | | NotifyOperationCompletion(SecuritySessionOperation.Issue, issuedToken, null, request.Headers.ReplyTo); |
| | 10 | 901 | | Message response = CreateReply(request, IssueResponseAction, replyMessage); |
| | 10 | 902 | | if (!issuedToken.IsCookieMode) |
| | | 903 | | { |
| | 10 | 904 | | _issuedTokenCache.AddContext(issuedToken); |
| | | 905 | | } |
| | 10 | 906 | | return response; |
| | | 907 | | } |
| | | 908 | | finally |
| | | 909 | | { |
| | 10 | 910 | | RemoveCachedTokensIfRequired(request.Properties.Security); |
| | 10 | 911 | | } |
| | 10 | 912 | | } |
| | | 913 | | |
| | | 914 | | internal static bool DoesSkiClauseMatchSigningToken(SecurityContextKeyIdentifierClause skiClause, Message reques |
| | | 915 | | { |
| | 10 | 916 | | SecurityMessageProperty securityProperty = request.Properties.Security; |
| | 10 | 917 | | if (securityProperty == null) |
| | | 918 | | { |
| | 0 | 919 | | throw TraceUtility.ThrowHelperWarning(new SecurityNegotiationException(SR.SFxSecurityContextPropertyMiss |
| | | 920 | | } |
| | 10 | 921 | | SecurityContextSecurityToken sct = (securityProperty.ProtectionToken != null) ? (securityProperty.Protection |
| | 10 | 922 | | if (sct != null && skiClause.Matches(sct.ContextId, sct.KeyGeneration)) |
| | | 923 | | { |
| | 0 | 924 | | return true; |
| | | 925 | | } |
| | | 926 | | |
| | 10 | 927 | | if (securityProperty.HasIncomingSupportingTokens) |
| | | 928 | | { |
| | 20 | 929 | | for (int i = 0; i < securityProperty.IncomingSupportingTokens.Count; ++i) |
| | | 930 | | { |
| | 10 | 931 | | if (securityProperty.IncomingSupportingTokens[i].SecurityTokenAttachmentMode == SecurityTokenAttachm |
| | | 932 | | { |
| | 10 | 933 | | sct = securityProperty.IncomingSupportingTokens[i].SecurityToken as SecurityContextSecurityToken |
| | 10 | 934 | | if (sct != null && skiClause.Matches(sct.ContextId, sct.KeyGeneration)) |
| | | 935 | | { |
| | 10 | 936 | | return true; |
| | | 937 | | } |
| | | 938 | | } |
| | | 939 | | } |
| | | 940 | | } |
| | 0 | 941 | | return false; |
| | | 942 | | } |
| | | 943 | | |
| | | 944 | | private static Message CreateReply(Message request, XmlDictionaryString action, BodyWriter body) |
| | | 945 | | { |
| | 10 | 946 | | if (request.Headers.MessageId != null) |
| | | 947 | | { |
| | 10 | 948 | | Message reply = Message.CreateMessage(request.Version, ActionHeader.Create(action, request.Version.Addre |
| | 10 | 949 | | reply.InitializeReply(request); |
| | 10 | 950 | | return reply; |
| | | 951 | | } |
| | | 952 | | else |
| | | 953 | | { |
| | | 954 | | // the message id may not be present if MapToHttp is true |
| | 0 | 955 | | return Message.CreateMessage(request.Version, ActionHeader.Create(action, request.Version.Addressing), b |
| | | 956 | | } |
| | | 957 | | } |
| | | 958 | | |
| | | 959 | | private Message ProcessRequest(Message request) |
| | | 960 | | { |
| | 10 | 961 | | SecuritySessionOperation operation = SecuritySessionOperation.None; |
| | | 962 | | try |
| | | 963 | | { |
| | 10 | 964 | | if (request == null) |
| | | 965 | | { |
| | 0 | 966 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(request)); |
| | | 967 | | } |
| | 10 | 968 | | if (request.Headers.Action == IssueAction.Value) |
| | | 969 | | { |
| | 10 | 970 | | operation = SecuritySessionOperation.Issue; |
| | 10 | 971 | | return ProcessIssueRequest(request); |
| | | 972 | | } |
| | 0 | 973 | | else if (request.Headers.Action == RenewAction.Value) |
| | | 974 | | { |
| | 0 | 975 | | operation = SecuritySessionOperation.Renew; |
| | 0 | 976 | | return ProcessRenewRequest(request); |
| | | 977 | | } |
| | | 978 | | else |
| | | 979 | | { |
| | 0 | 980 | | throw TraceUtility.ThrowHelperWarning(new SecurityNegotiationException(SR.Format(SR.InvalidActionFor |
| | | 981 | | } |
| | | 982 | | } |
| | 0 | 983 | | catch (Exception e) |
| | | 984 | | { |
| | 0 | 985 | | if (Fx.IsFatal(e)) |
| | | 986 | | { |
| | 0 | 987 | | throw; |
| | | 988 | | } |
| | | 989 | | |
| | 0 | 990 | | return HandleOperationException(operation, request, e); |
| | | 991 | | } |
| | 10 | 992 | | } |
| | | 993 | | |
| | 44 | 994 | | internal SecuritySessionHost RequestSecurityTokenListener { get; private set; } |
| | | 995 | | |
| | | 996 | | private void SetupSessionListener() |
| | | 997 | | { |
| | | 998 | | //ChannelBuilder channelBuilder = new ChannelBuilder(this.IssuerBindingContext, false); //TODO addChannelDem |
| | | 999 | | //channelBuilder.Binding.Elements.Insert(0, new ReplyAdapterBindingElement()); |
| | | 1000 | | //channelBuilder.Binding.Elements.Insert(0, new SecuritySessionAuthenticatorBindingElement(this)); |
| | | 1001 | | |
| | 22 | 1002 | | List<string> supportedMessageActions = new List<string> |
| | 22 | 1003 | | { |
| | 22 | 1004 | | IssueAction.Value, |
| | 22 | 1005 | | RenewAction.Value |
| | 22 | 1006 | | }; |
| | 22 | 1007 | | SecurityBindingElement securityBindingElement = IssuerBindingContext.Binding.Elements.Find<SecurityBindingEl |
| | 88 | 1008 | | foreach (SecurityTokenParameters stp in new SecurityTokenParametersEnumerable(securityBindingElement)) |
| | | 1009 | | { |
| | 22 | 1010 | | if (stp is SecureConversationSecurityTokenParameters) |
| | | 1011 | | { |
| | 22 | 1012 | | SecureConversationSecurityTokenParameters scstp = (SecureConversationSecurityTokenParameters)stp; |
| | 22 | 1013 | | if (!scstp.CanRenewSession) |
| | | 1014 | | { |
| | 0 | 1015 | | supportedMessageActions.Remove(RenewAction.Value); |
| | 0 | 1016 | | break; |
| | | 1017 | | } |
| | | 1018 | | } |
| | | 1019 | | } |
| | 22 | 1020 | | MessageFilter issueAndRenewFilter = new SessionActionFilter(_standardsManager, supportedMessageActions.ToArr |
| | 22 | 1021 | | SecuritySessionHost sessionListener = new SecuritySessionHost(this, issueAndRenewFilter, ListenUri); |
| | 22 | 1022 | | RequestSecurityTokenListener = sessionListener; |
| | 22 | 1023 | | } |
| | | 1024 | | |
| | | 1025 | | |
| | | 1026 | | internal void BuildResponderChannelListener<TChannel>(BindingContext context, SecurityServiceDispatcher security |
| | | 1027 | | where TChannel : class, IChannel |
| | | 1028 | | { |
| | 22 | 1029 | | SecurityCredentialsManager securityCredentials = IssuerBindingContext.BindingParameters.Find<SecurityCredent |
| | 22 | 1030 | | if (securityCredentials == null) |
| | | 1031 | | { |
| | 0 | 1032 | | securityCredentials = ServiceCredentials.CreateDefaultCredentials(); |
| | | 1033 | | } |
| | 22 | 1034 | | _bootstrapSecurityBindingElement.ReaderQuotas = IssuerBindingContext.GetInnerProperty<XmlDictionaryReaderQuo |
| | 22 | 1035 | | if (_bootstrapSecurityBindingElement.ReaderQuotas == null) |
| | | 1036 | | { |
| | 0 | 1037 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.EncodingBindi |
| | | 1038 | | } |
| | | 1039 | | |
| | 22 | 1040 | | TransportBindingElement transportBindingElement = context.RemainingBindingElements.Find<TransportBindingElem |
| | 22 | 1041 | | if (transportBindingElement != null) |
| | | 1042 | | { |
| | 22 | 1043 | | _bootstrapSecurityBindingElement.MaxReceivedMessageSize = transportBindingElement.MaxReceivedMessageSize |
| | | 1044 | | } |
| | | 1045 | | |
| | 22 | 1046 | | SecurityProtocolFactory bootstrapSecurityProtocolFactory = _bootstrapSecurityBindingElement.CreateSecurityPr |
| | 22 | 1047 | | if (bootstrapSecurityProtocolFactory is MessageSecurityProtocolFactory) |
| | | 1048 | | { |
| | 0 | 1049 | | MessageSecurityProtocolFactory soapBindingFactory = (MessageSecurityProtocolFactory)bootstrapSecurityPro |
| | 0 | 1050 | | soapBindingFactory.ApplyConfidentiality = soapBindingFactory.ApplyIntegrity |
| | 0 | 1051 | | = soapBindingFactory.RequireConfidentiality = soapBindingFactory.RequireIntegrity = true; |
| | | 1052 | | |
| | 0 | 1053 | | soapBindingFactory.ProtectionRequirements.IncomingSignatureParts.ChannelParts.IsBodyIncluded = true; |
| | 0 | 1054 | | soapBindingFactory.ProtectionRequirements.OutgoingSignatureParts.ChannelParts.IsBodyIncluded = true; |
| | | 1055 | | |
| | 0 | 1056 | | MessagePartSpecification bodyPart = new MessagePartSpecification(true); |
| | 0 | 1057 | | soapBindingFactory.ProtectionRequirements.OutgoingSignatureParts.AddParts(bodyPart, IssueResponseAction) |
| | 0 | 1058 | | soapBindingFactory.ProtectionRequirements.OutgoingEncryptionParts.AddParts(bodyPart, IssueResponseAction |
| | 0 | 1059 | | soapBindingFactory.ProtectionRequirements.OutgoingSignatureParts.AddParts(bodyPart, RenewResponseAction) |
| | 0 | 1060 | | soapBindingFactory.ProtectionRequirements.OutgoingEncryptionParts.AddParts(bodyPart, RenewResponseAction |
| | | 1061 | | |
| | 0 | 1062 | | soapBindingFactory.ProtectionRequirements.IncomingSignatureParts.AddParts(bodyPart, IssueAction); |
| | 0 | 1063 | | soapBindingFactory.ProtectionRequirements.IncomingEncryptionParts.AddParts(bodyPart, IssueAction); |
| | 0 | 1064 | | soapBindingFactory.ProtectionRequirements.IncomingSignatureParts.AddParts(bodyPart, RenewAction); |
| | 0 | 1065 | | soapBindingFactory.ProtectionRequirements.IncomingEncryptionParts.AddParts(bodyPart, RenewAction); |
| | | 1066 | | } |
| | | 1067 | | |
| | 22 | 1068 | | SupportingTokenParameters renewSupportingTokenParameters = new SupportingTokenParameters(); |
| | 22 | 1069 | | SecurityContextSecurityTokenParameters sctParameters = new SecurityContextSecurityTokenParameters |
| | 22 | 1070 | | { |
| | 22 | 1071 | | RequireDerivedKeys = IssuedSecurityTokenParameters.RequireDerivedKeys |
| | 22 | 1072 | | }; |
| | 22 | 1073 | | renewSupportingTokenParameters.Endorsing.Add(sctParameters); |
| | 22 | 1074 | | bootstrapSecurityProtocolFactory.SecurityBindingElement.OperationSupportingTokenParameters.Add(RenewAction.V |
| | 22 | 1075 | | bootstrapSecurityProtocolFactory.SecurityTokenManager = new SessionRenewSecurityTokenManager(bootstrapSecuri |
| | | 1076 | | |
| | | 1077 | | //We are passing as arguments to use existing dispatcher instead of creating another forwarding dispatcher |
| | | 1078 | | // SecurityChannelListener<TChannel> securityChannelListener = new SecurityChannelListener<TChannel>( |
| | | 1079 | | // this.bootstrapSecurityBindingElement, this.IssuerBindingContext); |
| | 22 | 1080 | | securityServiceDispatcher.SecurityProtocolFactory = bootstrapSecurityProtocolFactory; |
| | 22 | 1081 | | securityServiceDispatcher.SendUnsecuredFaults = true; |
| | 22 | 1082 | | if (bootstrapSecurityProtocolFactory.ListenUri == null) |
| | 22 | 1083 | | bootstrapSecurityProtocolFactory.ListenUri = _listenUri; |
| | 22 | 1084 | | bootstrapSecurityProtocolFactory.OpenAsync(ServiceDefaults.OpenTimeout); |
| | | 1085 | | //TODO if/when we add support for composite duplex bindings, this will need to be false if the binding is a |
| | | 1086 | | //securityServiceDispatcher.SendUnsecuredFaults = !SecurityUtils.IsCompositeDuplexBinding(context); |
| | | 1087 | | |
| | | 1088 | | // ChannelBuilder channelBuilder = new ChannelBuilder(context, true); |
| | | 1089 | | // securityChannelListener.InitializeListener(channelBuilder); |
| | 22 | 1090 | | _shouldMatchRstWithEndpointFilter = SecurityUtils.ShouldMatchRstWithEndpointFilter(_bootstrapSecurityBinding |
| | | 1091 | | //return securityChannelListener; |
| | 22 | 1092 | | } |
| | | 1093 | | |
| | | 1094 | | internal class SecuritySessionHost //: ServiceHostBase |
| | | 1095 | | { |
| | | 1096 | | //ChannelBuilder channelBuilder; |
| | | 1097 | | private readonly MessageFilter _filter; |
| | | 1098 | | private readonly Uri _listenUri; |
| | | 1099 | | private readonly SecuritySessionSecurityTokenAuthenticator _authenticator; |
| | | 1100 | | |
| | 22 | 1101 | | public SecuritySessionHost(SecuritySessionSecurityTokenAuthenticator authenticator, MessageFilter filter, Ur |
| | | 1102 | | { |
| | 22 | 1103 | | _authenticator = authenticator; |
| | 22 | 1104 | | _filter = filter; |
| | 22 | 1105 | | _listenUri = listenUri; |
| | 22 | 1106 | | } |
| | | 1107 | | |
| | | 1108 | | internal ChannelDispatcher InitializeRuntime(SecurityServiceDispatcher securityDispatcher) |
| | | 1109 | | { |
| | 22 | 1110 | | if (securityDispatcher.AcceptorChannelType.Equals(typeof(IReplyChannel))) |
| | | 1111 | | { |
| | 19 | 1112 | | return InitializeRuntime<IReplyChannel>(securityDispatcher); |
| | | 1113 | | } |
| | | 1114 | | |
| | 3 | 1115 | | if (securityDispatcher.AcceptorChannelType.Equals(typeof(IDuplexSessionChannel))) |
| | | 1116 | | { |
| | 3 | 1117 | | return InitializeRuntime<IDuplexSessionChannel>(securityDispatcher); |
| | | 1118 | | } |
| | | 1119 | | |
| | 0 | 1120 | | throw new NotImplementedException(); |
| | | 1121 | | } |
| | | 1122 | | |
| | | 1123 | | internal ChannelDispatcher InitializeRuntime<TChannel>(SecurityServiceDispatcher securityDispatcher) where T |
| | | 1124 | | { |
| | 22 | 1125 | | MessageFilter contractFilter = _filter; |
| | 22 | 1126 | | int filterPriority = int.MaxValue - 10; |
| | 22 | 1127 | | List<Type> endpointChannelTypes = new List<Type> { typeof(IReplyChannel), |
| | 22 | 1128 | | typeof(IDuplexChannel), |
| | 22 | 1129 | | typeof(IReplySessionChannel), |
| | 22 | 1130 | | typeof(IDuplexSessionChannel) }; |
| | | 1131 | | |
| | | 1132 | | // IChannelListener listener = null; |
| | | 1133 | | // BindingParameterCollection parameters = new BindingParameterCollection(this.channelBuilder.BindingPa |
| | | 1134 | | // Binding binding = this.channelBuilder.Binding; |
| | | 1135 | | // binding.ReceiveTimeout = this.authenticator.NegotiationTimeout; |
| | | 1136 | | // parameters.Add(new ChannelDemuxerFilter(contractFilter, filterPriority)); |
| | | 1137 | | // DispatcherBuilder.MaybeCreateListener(true, endpointChannelTypes, binding, parameters, |
| | | 1138 | | // this.listenUri, "", ListenUriMode.Explicit, this.ServiceThrottle |
| | | 1139 | | // if (listener == null) |
| | | 1140 | | // { |
| | | 1141 | | // throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Forma |
| | | 1142 | | // } |
| | | 1143 | | |
| | | 1144 | | //Replacing above code by below 3 lines.(adding securityservicedispatcher to demuxer, how to respond) |
| | | 1145 | | |
| | 22 | 1146 | | Binding binding = _authenticator.IssuerBindingContext.Binding; |
| | 22 | 1147 | | binding.ReceiveTimeout = _authenticator.NegotiationTimeout; |
| | 22 | 1148 | | securityDispatcher.ChannelBuilder.AddServiceDispatcher<TChannel>(securityDispatcher, new ChannelDemuxerF |
| | | 1149 | | |
| | | 1150 | | //Injecting here the BuildResponderChannelListener |
| | 22 | 1151 | | _authenticator.BuildResponderChannelListener<TChannel>(_authenticator.IssuerBindingContext, securityDisp |
| | | 1152 | | //end |
| | | 1153 | | |
| | 22 | 1154 | | var bindingQname = new XmlQualifiedName(binding.Name, binding.Namespace); |
| | 22 | 1155 | | var channelDispatcher = new ChannelDispatcher(_listenUri, binding, bindingQname.ToString(), binding, end |
| | 22 | 1156 | | { |
| | 22 | 1157 | | MessageVersion = binding.MessageVersion, |
| | 22 | 1158 | | ManualAddressing = true |
| | 22 | 1159 | | }; |
| | | 1160 | | // channelDispatcher.ServiceThrottle = new ServiceThrottle(this); |
| | | 1161 | | // channelDispatcher.ServiceThrottle.MaxConcurrentCalls = this.authenticator.MaximumConcurrentNegotiati |
| | | 1162 | | // channelDispatcher.ServiceThrottle.MaxConcurrentSessions = this.authenticator.MaximumConcurrentNegoti |
| | | 1163 | | |
| | 22 | 1164 | | EndpointDispatcher endpointDispatcher = new EndpointDispatcher(new EndpointAddress(_listenUri), "IssueAn |
| | 22 | 1165 | | endpointDispatcher.DispatchRuntime.SingletonInstanceContext = new InstanceContext(null, _authenticator, |
| | 22 | 1166 | | endpointDispatcher.DispatchRuntime.ConcurrencyMode = ConcurrencyMode.Multiple; |
| | 22 | 1167 | | endpointDispatcher.AddressFilter = new MatchAllMessageFilter(); |
| | 22 | 1168 | | endpointDispatcher.ContractFilter = contractFilter; |
| | 22 | 1169 | | endpointDispatcher.FilterPriority = filterPriority; |
| | 22 | 1170 | | endpointDispatcher.DispatchRuntime.PrincipalPermissionMode = PrincipalPermissionMode.None; |
| | 22 | 1171 | | endpointDispatcher.DispatchRuntime.InstanceContextProvider = new SingletonInstanceContextProvider(endpoi |
| | 22 | 1172 | | endpointDispatcher.DispatchRuntime.SynchronizationContext = null; |
| | | 1173 | | |
| | 22 | 1174 | | if (_authenticator.IssuerBindingContext != null && _authenticator.IssuerBindingContext.BindingParameters |
| | | 1175 | | { |
| | 22 | 1176 | | ServiceAuthenticationManager serviceAuthenticationManager = _authenticator.IssuerBindingContext.Bind |
| | 22 | 1177 | | if (serviceAuthenticationManager != null) |
| | | 1178 | | { |
| | 0 | 1179 | | endpointDispatcher.DispatchRuntime.ServiceAuthenticationManager = new SCTServiceAuthenticationMa |
| | | 1180 | | } |
| | | 1181 | | } |
| | | 1182 | | |
| | 22 | 1183 | | DispatchOperation operation = new DispatchOperation(endpointDispatcher.DispatchRuntime, "*", MessageHead |
| | 22 | 1184 | | { |
| | 22 | 1185 | | Formatter = new MessageOperationFormatter(), |
| | 22 | 1186 | | Invoker = new SecuritySessionAuthenticatorInvoker(_authenticator) |
| | 22 | 1187 | | }; |
| | | 1188 | | |
| | 22 | 1189 | | endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation = operation; |
| | 22 | 1190 | | channelDispatcher.Endpoints.Add(endpointDispatcher); |
| | 22 | 1191 | | channelDispatcher.Init(); |
| | 22 | 1192 | | Task openTask = channelDispatcher.OpenAsync(); |
| | | 1193 | | Fx.Assert(openTask.IsCompleted, "ChannelDispatcher should open synchronously"); |
| | 22 | 1194 | | openTask.GetAwaiter().GetResult(); |
| | 22 | 1195 | | return channelDispatcher; |
| | | 1196 | | } |
| | | 1197 | | |
| | | 1198 | | private class SecuritySessionAuthenticatorInvoker : IOperationInvoker |
| | | 1199 | | { |
| | | 1200 | | private readonly SecuritySessionSecurityTokenAuthenticator _parent; |
| | | 1201 | | |
| | 22 | 1202 | | internal SecuritySessionAuthenticatorInvoker(SecuritySessionSecurityTokenAuthenticator parent) |
| | | 1203 | | { |
| | 22 | 1204 | | _parent = parent; |
| | 22 | 1205 | | } |
| | | 1206 | | |
| | 0 | 1207 | | public bool IsSynchronous { get { return true; } } |
| | | 1208 | | |
| | | 1209 | | public object[] AllocateInputs() |
| | | 1210 | | { |
| | 10 | 1211 | | return EmptyArray<object>.Allocate(1); |
| | | 1212 | | } |
| | | 1213 | | |
| | | 1214 | | public ValueTask<(object returnValue, object[] outputs)> InvokeAsync(object instance, object[] inputs) |
| | | 1215 | | { |
| | 10 | 1216 | | object[] outputs = EmptyArray<object>.Allocate(0); |
| | 10 | 1217 | | if (!(inputs[0] is Message message)) |
| | | 1218 | | { |
| | 0 | 1219 | | return new ValueTask<(object returnValue, object[] outputs)>(((object)null, outputs)); |
| | | 1220 | | } |
| | 10 | 1221 | | object returnVal = _parent.ProcessRequest(message); |
| | 10 | 1222 | | return new ValueTask<(object returnValue, object[] outputs)>((returnVal, outputs)); |
| | | 1223 | | } |
| | | 1224 | | } |
| | | 1225 | | } |
| | | 1226 | | |
| | | 1227 | | private class SecuritySessionAuthenticatorBindingElement : BindingElement |
| | | 1228 | | { |
| | | 1229 | | private readonly SecuritySessionSecurityTokenAuthenticator _authenticator; |
| | | 1230 | | |
| | 0 | 1231 | | public SecuritySessionAuthenticatorBindingElement(SecuritySessionSecurityTokenAuthenticator authenticator) |
| | | 1232 | | { |
| | 0 | 1233 | | _authenticator = authenticator; |
| | 0 | 1234 | | } |
| | | 1235 | | |
| | | 1236 | | public override BindingElement Clone() |
| | | 1237 | | { |
| | 0 | 1238 | | return new SecuritySessionAuthenticatorBindingElement(_authenticator); |
| | | 1239 | | } |
| | | 1240 | | |
| | | 1241 | | public override T GetProperty<T>(BindingContext context) |
| | | 1242 | | { |
| | 0 | 1243 | | if (typeof(T) == typeof(ISecurityCapabilities)) |
| | | 1244 | | { |
| | 0 | 1245 | | return (T)(object)_authenticator.BootstrapSecurityBindingElement.GetProperty<ISecurityCapabilities>( |
| | | 1246 | | } |
| | | 1247 | | |
| | 0 | 1248 | | return context.GetInnerProperty<T>(); |
| | | 1249 | | } |
| | | 1250 | | } |
| | | 1251 | | |
| | | 1252 | | public class SessionRenewSecurityTokenManager : SecurityTokenManager |
| | | 1253 | | { |
| | | 1254 | | private readonly SecurityTokenManager _innerTokenManager; |
| | | 1255 | | private readonly SecurityTokenAuthenticator _renewTokenAuthenticator; |
| | | 1256 | | private readonly SecurityTokenResolver _renewTokenResolver; |
| | | 1257 | | |
| | 22 | 1258 | | public SessionRenewSecurityTokenManager(SecurityTokenManager innerTokenManager, SecurityTokenAuthenticator r |
| | 22 | 1259 | | SecurityTokenResolver renewTokenResolver) |
| | | 1260 | | { |
| | 22 | 1261 | | _innerTokenManager = innerTokenManager; |
| | 22 | 1262 | | _renewTokenAuthenticator = renewTokenAuthenticator; |
| | 22 | 1263 | | _renewTokenResolver = renewTokenResolver; |
| | 22 | 1264 | | } |
| | | 1265 | | |
| | | 1266 | | public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRe |
| | | 1267 | | { |
| | 44 | 1268 | | if (tokenRequirement == null) |
| | | 1269 | | { |
| | 0 | 1270 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(tokenRequirement)); |
| | | 1271 | | } |
| | | 1272 | | |
| | 44 | 1273 | | if (tokenRequirement.TokenType == ServiceModelSecurityTokenTypes.SecurityContext) |
| | | 1274 | | { |
| | 22 | 1275 | | outOfBandTokenResolver = _renewTokenResolver; |
| | 22 | 1276 | | return _renewTokenAuthenticator; |
| | | 1277 | | } |
| | | 1278 | | else |
| | | 1279 | | { |
| | 22 | 1280 | | return _innerTokenManager.CreateSecurityTokenAuthenticator(tokenRequirement, out outOfBandTokenResol |
| | | 1281 | | } |
| | | 1282 | | } |
| | | 1283 | | |
| | | 1284 | | public override SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement requirement) |
| | | 1285 | | { |
| | 0 | 1286 | | return _innerTokenManager.CreateSecurityTokenProvider(requirement); |
| | | 1287 | | } |
| | | 1288 | | |
| | | 1289 | | public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version) |
| | | 1290 | | { |
| | 0 | 1291 | | return _innerTokenManager.CreateSecurityTokenSerializer(version); |
| | | 1292 | | } |
| | | 1293 | | } |
| | | 1294 | | } |
| | | 1295 | | |
| | | 1296 | | internal class SessionActionFilter : HeaderFilter |
| | | 1297 | | { |
| | | 1298 | | private readonly SecurityStandardsManager _standardsManager; |
| | | 1299 | | private readonly string[] _actions; |
| | | 1300 | | |
| | | 1301 | | public SessionActionFilter(SecurityStandardsManager standardsManager, params string[] actions) |
| | | 1302 | | { |
| | | 1303 | | _actions = actions; |
| | | 1304 | | _standardsManager = standardsManager; |
| | | 1305 | | } |
| | | 1306 | | |
| | | 1307 | | public override bool Match(Message message) |
| | | 1308 | | { |
| | | 1309 | | for (int i = 0; i < _actions.Length; ++i) |
| | | 1310 | | { |
| | | 1311 | | if (message.Headers.Action == _actions[i]) |
| | | 1312 | | { |
| | | 1313 | | return _standardsManager.DoesMessageContainSecurityHeader(message); |
| | | 1314 | | } |
| | | 1315 | | } |
| | | 1316 | | return false; |
| | | 1317 | | } |
| | | 1318 | | } |
| | | 1319 | | } |