< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.IdentityModel.Tokens.SessionSecurityTokenHandler
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/IdentityModel/Tokens/SessionSecurityTokenHandler.cs
Line coverage
8%
Covered lines: 21
Uncovered lines: 217
Coverable lines: 238
Total lines: 803
Line coverage: 8.8%
Branch coverage
1%
Covered branches: 2
Total branches: 124
Branch coverage: 1.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/IdentityModel/Tokens/SessionSecurityTokenHandler.cs

#LineLine coverage
 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
 4using System;
 5using System.Collections.Generic;
 6using System.Collections.ObjectModel;
 7using System.IO;
 8using System.Runtime.Serialization;
 9using System.Runtime.Serialization.Formatters.Binary;
 10using System.Security.Claims;
 11using System.Xml;
 12using CoreWCF.IdentityModel.Claims;
 13using CoreWCF.IdentityModel.Configuration;
 14using CoreWCF.IdentityModel.Selectors;
 15using CoreWCF.Runtime;
 16using CoreWCF.Security;
 17using Microsoft.Extensions.DependencyInjection;
 18using SysUniqueId = System.Xml.UniqueId;
 19
 20namespace CoreWCF.IdentityModel.Tokens
 21{
 22    /// <summary>
 23    /// A <see cref="SecurityTokenHandler"/> that processes <see cref="SessionSecurityToken"/>.
 24    /// </summary>
 25    public class SessionSecurityTokenHandler : SecurityTokenHandler
 26    {
 127        private static readonly string s_useBinaryFormatter = "CoreWCF.IdentityModel.Tokens.UseBinaryFormatter";
 28
 29        private const string DefaultCookieElementName = "Cookie";
 30        private const string DefaultCookieNamespace = "http://schemas.microsoft.com/ws/2006/05/security";
 31        private const string SecureConversationTokenIdentifier = "http://schemas.microsoft.com/ws/2006/05/servicemodel/t
 132        public static readonly TimeSpan DefaultLifetime = TimeSpan.FromHours(10);
 33       // public static readonly ReadOnlyCollection<CookieTransform> DefaultCookieTransforms = (new List<CookieTransform
 434        private TimeSpan _tokenLifetime = DefaultLifetime;
 35
 36        /// <summary>
 37        /// Initializes an instance of <see cref="SessionSecurityTokenHandler"/>
 38        /// </summary>
 39        /// <remarks>
 40        /// Properties are used for defaults:
 41        /// DefaultCookieTransforms
 42        /// DefaultLifetime
 43        /// </remarks>
 44        //public SessionSecurityTokenHandler()
 45        //    : this(SessionSecurityTokenHandler.DefaultCookieTransforms)
 46        //{
 47        //}
 48
 49        /// <summary>
 50        /// Initializes an instance of <see cref="SessionSecurityTokenHandler"/>
 51        /// </summary>
 52        /// <param name="transforms">The transforms to apply when encoding the cookie.</param>
 53        /// <remarks>
 54        /// Properties are used for the remaining defaults:
 55        /// DefaultLifetime
 56        /// </remarks>
 57        public SessionSecurityTokenHandler(ReadOnlyCollection<CookieTransform> transforms)
 458            : this(transforms, DefaultLifetime)
 459        { }
 60
 61        /// <summary>
 62        /// Initializes an instance of <see cref="SessionSecurityTokenHandler"/>
 63        /// </summary>
 64        /// <param name="transforms">The transforms to apply when encoding the cookie.</param>
 65        /// <param name="tokenLifetime">The default for a token.</param>
 66        /// <exception cref="ArgumentNullException">Is thrown if 'transforms' is null.</exception>
 67        /// <exception cref="InvalidOperationException">Is thrown if 'tokenLifetime' is less than or equal to TimeSpan.Z
 468        public SessionSecurityTokenHandler(ReadOnlyCollection<CookieTransform> transforms, TimeSpan tokenLifetime)
 69        {
 470            if (tokenLifetime <= TimeSpan.Zero)
 71            {
 072                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.ID0
 73            }
 74
 475            Transforms = transforms ?? throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(transform
 476            _tokenLifetime = tokenLifetime;
 477        }
 78
 79        internal static ReadOnlyCollection<CookieTransform> GetDefaultCookieTransforms(IServiceProvider serviceProvider)
 80        {
 481            var list = new List<CookieTransform>
 482            {
 483                new DeflateCookieTransform(),
 484                serviceProvider.GetRequiredService<ProtectedDataCookieTransform>()
 485            };
 486            return list.AsReadOnly();
 87        }
 88
 89        /// <summary>
 90        /// Gets the name for the cookie element.
 91        /// </summary>
 92        public virtual string CookieElementName
 93        {
 094            get { return DefaultCookieElementName; }
 95        }
 96
 97        /// <summary>
 98        /// Gets the namspace for the cookie element.
 99        /// </summary>
 100        public virtual string CookieNamespace
 101        {
 0102            get { return DefaultCookieNamespace; }
 103        }
 104
 105        /// <summary>
 106        /// Applies Transforms to the cookie.
 107        /// </summary>
 108        /// <param name="cookie">The cookie that will be transformed.</param>
 109        /// <param name="outbound">Controls if the cookie should be encoded (true) or decoded (false)</param>
 110        /// <returns>Encoded cookie.</returns>
 111        protected virtual byte[] ApplyTransforms(byte[] cookie, bool outbound)
 112        {
 0113            byte[] transformedCookie = cookie;
 114
 0115            if (Transforms == null)
 116            {
 0117                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.ID4
 118            }
 119
 0120            if (outbound)
 121            {
 0122                for (int i = 0; i < Transforms.Count; i++)
 123                {
 0124                    transformedCookie = Transforms[i].Encode(transformedCookie);
 125                }
 126            }
 127            else
 128            {
 0129                for (int i = Transforms.Count; i > 0; i--)
 130                {
 0131                    transformedCookie = Transforms[i - 1].Decode(transformedCookie);
 132                }
 133            }
 134
 0135            return transformedCookie;
 136        }
 137
 138        /// <summary>
 139        /// Checks the reader if this is a SecurityContextToken.
 140        /// </summary>
 141        /// <param name=nameof(reader)>XmlReader over the incoming SecurityToken.</param>
 142        /// <returns>'True' if the reader points to a SecurityContextToken.</returns>
 143        /// <exception cref="ArgumentNullException">The input argument 'reader' is null.</exception>
 144        public override bool CanReadToken(XmlReader reader)
 145        {
 0146            if (reader == null)
 147            {
 0148                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(reader));
 149            }
 150
 0151            return (reader.IsStartElement(WSSecureConversationFeb2005Constants.ElementNames.Name, WSSecureConversationFe
 0152                  || reader.IsStartElement(WSSecureConversation13Constants.ElementNames.Name, WSSecureConversation13Cons
 153        }
 154
 155        /// <summary>
 156        /// Indicates whether this handler supports validation of tokens.
 157        /// </summary>
 158        /// <returns>'True' if the class is capable of SecurityToken validation.</returns>
 159        public override bool CanValidateToken
 160        {
 0161            get { return true; }
 162        }
 163
 164        /// <summary>
 165        /// Gets information on whether this Token Handler can write tokens.
 166        /// </summary>
 167        public override bool CanWriteToken
 168        {
 169            get
 170            {
 0171                return true;
 172            }
 173        }
 174
 175        /// <summary>
 176        /// Creates a security token based on a token descriptor.
 177        /// </summary>
 178        /// <param name=nameof(tokenDescriptor)>The token descriptor.</param>
 179        /// <returns>A security token.</returns>
 180        /// <exception cref="ArgumentNullException">Thrown if 'tokenDescriptor' is null.</exception>
 181        public override SecurityToken CreateToken(SecurityTokenDescriptor tokenDescriptor)
 182        {
 0183            if (null == tokenDescriptor)
 184            {
 0185                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(tokenDescriptor));
 186            }
 187
 0188            if (Configuration == null)
 189            {
 0190                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.ID4
 191            }
 192
 0193            ClaimsPrincipal principal = new ClaimsPrincipal(tokenDescriptor.Subject);
 194
 0195            if (Configuration.SaveBootstrapContext)
 196            {
 0197                SecurityTokenHandlerCollection bootstrapTokenCollection = CreateBootstrapTokenHandlerCollection();
 0198                if (!bootstrapTokenCollection.CanWriteToken(tokenDescriptor.Token))
 199                {
 0200                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR
 201                }
 202
 0203                (principal.Identities as ReadOnlyCollection<ClaimsIdentity>)[0].BootstrapContext = new BootstrapContext(
 204            }
 205
 0206            DateTime validFrom = (tokenDescriptor.Lifetime.Created.HasValue) ? (DateTime)tokenDescriptor.Lifetime.Create
 0207            DateTime validTo = (tokenDescriptor.Lifetime.Expires.HasValue) ? (DateTime)tokenDescriptor.Lifetime.Expires 
 208
 0209            return new SessionSecurityToken(principal, null, validFrom, validTo);
 210        }
 211
 212        /// <summary>
 213        /// Creates a <see cref="SessionSecurityToken"/> based on an <see cref="ClaimsPrincipal"/> and a valid time rang
 214        /// </summary>
 215        /// <param name="principal"><see cref="ClaimsPrincipal"/></param>
 216        /// <param name="context">Caller defined context string</param>
 217        /// <param name="endpointId">Identifier of the endpoint to which the token is scoped.</param>
 218        /// <param name="validFrom">Earliest valid time.</param>
 219        /// <param name="validTo">Latest valid time.</param>
 220        public virtual SessionSecurityToken CreateSessionSecurityToken(
 221            ClaimsPrincipal principal,
 222            string context,
 223            string endpointId,
 224            DateTime validFrom,
 225            DateTime validTo)
 226        {
 0227            if (null == principal)
 228            {
 0229                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("principal");
 230            }
 231
 0232            if (Configuration == null)
 233            {
 0234                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.ID4
 235            }
 236
 0237            return new SessionSecurityToken(principal, context, endpointId, validFrom, validTo);
 238        }
 239
 240        /// <summary>
 241        /// Gets the default token lifetime
 242        /// </summary>
 243        public static TimeSpan DefaultTokenLifetime
 244        {
 0245            get { return DefaultLifetime; }
 246        }
 247
 248        /// <summary>
 249        /// Reads the SessionSecurityToken from a stream of bytes.
 250        /// </summary>
 251        /// <param name=nameof(token)>token.</param>
 252        /// <param name="tokenResolver">SecurityTokenResolver that can be used to resolve the SessionSecurityToken.</par
 253        /// <returns>Instance of SessionSecurityToken.</returns>
 254        public virtual SecurityToken ReadToken(byte[] token, SecurityTokenResolver tokenResolver)
 255        {
 256            // Our implementation of ReadToken( byte[] ) will always return null. We make the above call not to
 257            // break SharePoint. SharePoint has overridden ReadToken(byte[] token) and expect the SessionAuthenticationM
 258            // call that. So SessionAuthenticationModule will calls this method which does the correct thing.
 0259            using (XmlReader reader = XmlDictionaryReader.CreateTextReader(token, XmlDictionaryReaderQuotas.Max))
 260            {
 0261                return ReadToken(reader, tokenResolver);
 262            }
 0263        }
 264
 265        /// <summary>
 266        /// Reads the SessionSecurityToken from the given reader.
 267        /// </summary>
 268        /// <param name=nameof(reader)>XmlReader over the SessionSecurityToken.</param>
 269        /// <returns>An instance of <see cref="SessionSecurityToken"/>.</returns>
 270        /// <exception cref="ArgumentNullException">The input argument 'reader' is null.</exception>
 271        /// <exception cref="SecurityTokenException">The 'reader' is not positioned at a SessionSecurityToken
 272        /// or the SessionSecurityToken cannot be read.</exception>
 273        public override SecurityToken ReadToken(XmlReader reader)
 274        {
 0275            throw new NotImplementedException();
 276           // return this.ReadToken(reader, EmptySecurityTokenResolver.Instance);
 277        }
 278
 279        /// <summary>
 280        /// Reads the SessionSecurityToken from the given reader.
 281        /// </summary>
 282        /// <param name=nameof(reader)>XmlReader over the SessionSecurityToken.</param>
 283        /// <param name="tokenResolver">SecurityTokenResolver that can used to resolve SessionSecurityToken.</param>
 284        /// <returns>An instance of <see cref="SessionSecurityToken"/>.</returns>
 285        /// <exception cref="ArgumentNullException">The input argument 'reader' is null.</exception>
 286        /// <exception cref="SecurityTokenException">The 'reader' is not positioned at a SessionSecurityToken
 287        /// or the SessionSecurityToken cannot be read.</exception>
 288        public override SecurityToken ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver)
 289        {
 0290            if (reader == null)
 291            {
 0292                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(reader));
 293            }
 294
 0295            if (tokenResolver == null)
 296            {
 0297                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(tokenResolver));
 298            }
 299
 0300            SysUniqueId keyGeneration = null;
 0301            SecurityToken securityContextToken = null;
 0302            SessionDictionary dictionary = SessionDictionary.Instance;
 303
 0304            XmlDictionaryReader dicReader = XmlDictionaryReader.CreateDictionaryReader(reader);
 305
 306
 307            string ns;
 308            string identifier;
 309            string instance;
 0310            if (dicReader.IsStartElement(WSSecureConversationFeb2005Constants.ElementNames.Name, WSSecureConversationFeb
 311            {
 0312                ns = WSSecureConversationFeb2005Constants.Namespace;
 0313                identifier = WSSecureConversationFeb2005Constants.ElementNames.Identifier;
 0314                instance = WSSecureConversationFeb2005Constants.ElementNames.Instance;
 315            }
 0316            else if (dicReader.IsStartElement(WSSecureConversation13Constants.ElementNames.Name, WSSecureConversation13C
 317            {
 0318                ns = WSSecureConversation13Constants.Namespace;
 0319                identifier = WSSecureConversation13Constants.ElementNames.Identifier;
 0320                instance = WSSecureConversation13Constants.ElementNames.Instance;
 321            }
 322            else
 323            {
 324                //
 325                // Something is wrong
 326                //
 0327                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(
 0328                    SR.Format(SR.ID4230, WSSecureConversationFeb2005Constants.ElementNames.Name, dicReader.Name)));
 329            }
 330
 0331            string id = dicReader.GetAttribute(WSUtilityConstants.Attributes.IdAttribute, WSUtilityConstants.NamespaceUR
 332
 0333            dicReader.ReadFullStartElement();
 0334            if (!dicReader.IsStartElement(identifier, ns))
 335            {
 0336                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(
 0337                    SR.Format(SR.ID4230, WSSecureConversation13Constants.ElementNames.Identifier, dicReader.Name)));
 338            }
 339
 0340            SysUniqueId contextId = dicReader.ReadElementContentAsUniqueId();
 0341            if (contextId == null || string.IsNullOrEmpty(contextId.ToString()))
 342            {
 0343                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.Format(SR.ID4242
 344            }
 345
 346            //
 347            // The token can be a renewed token, in which case we need to know the
 348            // instance id, which will be the secondary key to the context id for
 349            // cache lookups
 350            //
 0351            if (dicReader.IsStartElement(instance, ns))
 352            {
 0353                keyGeneration = dicReader.ReadElementContentAsUniqueId();
 354            }
 355
 0356            if (dicReader.IsStartElement(CookieElementName, CookieNamespace))
 357            {
 358                SecurityContextKeyIdentifierClause sctClause;
 0359                if (keyGeneration == null)
 360                {
 0361                    sctClause = new SecurityContextKeyIdentifierClause(contextId);
 362                }
 363                else
 364                {
 0365                    sctClause = new SecurityContextKeyIdentifierClause(contextId, keyGeneration);
 366                }
 367
 368                // Get the token from the Cache, which is returned as an SCT
 0369                tokenResolver.TryResolveToken(sctClause, out SecurityToken cachedToken);
 0370                if (cachedToken != null)
 371                {
 0372                    securityContextToken = cachedToken;
 373
 0374                    dicReader.Skip();
 375                }
 376                else
 377                {
 378                    //
 379                    // CookieMode
 380                    //
 0381                    byte[] encodedCookie = dicReader.ReadElementContentAsBase64();
 382
 0383                    if (encodedCookie == null)
 384                    {
 0385                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.Format(S
 386                    }
 387                    //
 388                    // appply transforms
 389                    //
 0390                    byte[] decodedCookie = ApplyTransforms(encodedCookie, false);
 391
 0392                    securityContextToken = DeserializeSecurityToken(decodedCookie);
 393
 0394                    SessionSecurityToken sessionToken = securityContextToken as SessionSecurityToken;
 0395                    if (sessionToken != null && sessionToken.ContextId != contextId)
 396                    {
 0397                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.Format(S
 398                    }
 399
 0400                    if (sessionToken != null && sessionToken.Id != id)
 401                    {
 0402                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.Format(S
 403                    }
 404                }
 405            }
 406            else
 407            {
 408                SecurityContextKeyIdentifierClause sctClause;
 0409                if (keyGeneration == null)
 410                {
 0411                    sctClause = new SecurityContextKeyIdentifierClause(contextId);
 412                }
 413                else
 414                {
 0415                    sctClause = new SecurityContextKeyIdentifierClause(contextId, keyGeneration);
 416                }
 417
 0418                tokenResolver.TryResolveToken(sctClause, out SecurityToken cachedToken);
 419
 0420                if (cachedToken != null)
 421                {
 0422                    securityContextToken = cachedToken;
 423                }
 424            }
 425
 0426            dicReader.ReadEndElement();
 427
 0428            if (securityContextToken == null)
 429            {
 0430                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.Format(SR.ID4243
 431            }
 432
 0433            return securityContextToken;
 434        }
 435
 436        /// <summary>
 437        /// Gets or sets the TokenLifetime.
 438        /// </summary>
 439        public virtual TimeSpan TokenLifetime
 440        {
 0441            get { return _tokenLifetime; }
 442            set
 443            {
 0444                if (value <= TimeSpan.Zero)
 445                {
 0446                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(nameof(value), SR.Format(SR.ID0016));
 447                }
 448
 0449                _tokenLifetime = value;
 0450            }
 451        }
 452
 453        /// <summary>
 454        /// Gets the bootstrap token handler collection.
 455        /// </summary>
 456        private SecurityTokenHandlerCollection CreateBootstrapTokenHandlerCollection()
 457        {
 0458            SecurityTokenHandlerCollection tokenHandlerCollection = ContainingCollection ?? throw new NotSupportedExcept
 0459            return tokenHandlerCollection;
 460        }
 461
 462        /// <summary>
 463        /// Gets the token type URIs
 464        /// </summary>
 465        public override string[] GetTokenTypeIdentifiers()
 466        {
 8467            return new string[] { SecureConversationTokenIdentifier,
 8468                                 WSSecureConversation13Constants.TokenTypeURI,
 8469                                 WSSecureConversationFeb2005Constants.TokenTypeURI };
 470        }
 471
 472        /// <summary>
 473        /// Gets the type of token this handler can work with.
 474        /// </summary>
 475        public override Type TokenType
 476        {
 14477            get { return typeof(SessionSecurityToken); }
 478        }
 479
 480        /// <summary>
 481        /// Gets the transforms that will be applied to the cookie.
 482        /// </summary>
 4483        public ReadOnlyCollection<CookieTransform> Transforms { get; private set; }
 484
 485        /// <summary>
 486        /// Sets the transforms that will be applied to cookies.
 487        /// </summary>
 488        /// <param name="transforms">The <see cref="CookieTransform"/> objects to use.  </param>
 489        protected void SetTransforms(IEnumerable<CookieTransform> transforms)
 490        {
 0491            Transforms = new List<CookieTransform>(transforms).AsReadOnly();
 0492        }
 493
 494        /// <summary>
 495        /// Validates a <see cref="SessionSecurityToken"/>.
 496        /// </summary>
 497        /// <param name=nameof(token)>The <see cref="SessionSecurityToken"/> to validate.</param>
 498        /// <returns>A <see cref="ReadOnlyCollection{T}"/> of <see cref="ClaimsIdentity"/> representing the identities c
 499        /// <exception cref="ArgumentNullException">The parameter 'token' is null.</exception>
 500        /// <exception cref="ArgumentException">The token is not assignable from <see cref="SessionSecurityToken"/>.</ex
 501        public override ReadOnlyCollection<ClaimsIdentity> ValidateToken(SecurityToken token)
 502        {
 0503            if (token == null)
 504            {
 0505                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(token));
 506            }
 507
 0508            if (!(token is SessionSecurityToken sessionToken))
 509            {
 0510                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.ID4
 511            }
 512
 513            try
 514            {
 515                //if (DiagnosticUtility.ShouldTrace(TraceEventType.Verbose))
 516                //{
 517                //    TraceUtility.TraceEvent(
 518                //        TraceEventType.Verbose,
 519                //        TraceCode.Diagnostics,
 520                //        SR.Format(SR.TraceValidateToken),
 521                //        new SecurityTraceRecordHelper.TokenTraceRecord(token),
 522                //        null,
 523                //        null);
 524                //}
 525
 0526                ValidateSession(sessionToken);
 527
 528               // this.TraceTokenValidationSuccess(token);
 529
 0530                List<ClaimsIdentity> identitites = new List<ClaimsIdentity>(1);
 0531                identitites.AddRange(sessionToken.ClaimsPrincipal.Identities);
 0532                return identitites.AsReadOnly();
 533            }
 534            catch (Exception e)
 535            {
 0536                if (Fx.IsFatal(e))
 537                {
 0538                    throw;
 539                }
 540
 541               // this.TraceTokenValidationFailure(token, e.Message);
 0542                throw e;
 543            }
 0544        }
 545
 546        /// <summary>
 547        /// Validates a token and returns its claims.
 548        /// </summary>
 549        /// <param name=nameof(token)>The <see cref="SessionSecurityToken"/> to validate.</param>
 550        /// <param name="endpointId">Identifier to the endpoint to which the token is scoped.</param>
 551        /// <returns>A <see cref="ReadOnlyCollection{T}"/> of <see cref="ClaimsIdentity"/> representing the identities c
 552        /// <exception cref="ArgumentNullException">The parameter 'token' is null.</exception>
 553        /// <exception cref="ArgumentNullException">The parameter 'endpointId' is null.</exception>
 554        /// <exception cref="SecurityTokenException">token.EndpointId != endpointId.</exception>
 555        public virtual ReadOnlyCollection<ClaimsIdentity> ValidateToken(SessionSecurityToken token, string endpointId)
 556        {
 0557            if (token == null)
 558            {
 0559                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(token));
 560            }
 561
 0562            if (endpointId == null)
 563            {
 0564                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(endpointId));
 565            }
 566
 567            // We consider SessionTokens with String.Empty as the endpoint Id to be
 568            // globally scoped tokens. This in insecure, we are allowing this only
 569            // for compatibility with customers who have overriden SessionSecurityTokenHandler.
 0570            if (!string.IsNullOrEmpty(token.EndpointId))
 571            {
 0572                if (token.EndpointId != endpointId)
 573                {
 0574                    string errorMessage = SR.Format(SR.ID4291, token);
 575                    //this.TraceTokenValidationFailure(token, errorMessage);
 0576                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(errorMessage));
 577                }
 578            }
 579
 0580            return ValidateToken(token);
 581        }
 582
 583        /// <summary>
 584        /// Checks the valid time of a SecurityToken.
 585        /// </summary>
 586        /// <remarks>
 587        /// The token is invalid if the securityToken.ValidFrom &gt; DateTime.UtcNow OR securityToken.ValidTo &lt; DateT
 588        /// </remarks>
 589        /// <param name=nameof(token)>The <see cref="SessionSecurityToken"/> to validate.</param>
 590        /// <exception cref="ArgumentNullException">Thrown if 'securityToken' is null.</exception>
 591        /// <exception cref="InvalidOperationException">Thrown if 'Configuration' is null.</exception>
 592        /// <exception cref="SecurityTokenNotYetValidException">Thrown if securityToken.ValidFrom &gt; DateTime.UtcNow.<
 593        /// <exception cref="SecurityTokenExpiredException">Thrown if securityToken.ValidTo &lt; DateTime.UtcNow.</excep
 594        protected virtual void ValidateSession(SessionSecurityToken securityToken)
 595        {
 0596            if (securityToken == null)
 597            {
 0598                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(securityToken));
 599            }
 600
 0601            if (Configuration == null)
 602            {
 0603                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.ID4
 604            }
 605
 606            Fx.Assert(Configuration != null, SR.Format(SR.ID8027));
 607
 0608            DateTime utcNow = DateTime.UtcNow;
 609
 610            // apply clock skew here.
 0611            DateTime maxTime = utcNow.Add(Configuration.MaxClockSkew);
 0612            DateTime minTime = utcNow.Add(-Configuration.MaxClockSkew);
 613
 0614            if (securityToken.ValidFrom > maxTime)
 615            {
 0616                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Exception(SR.Format(SR.ID4255, securityTok
 617            }
 618
 0619            if (securityToken.ValidTo < minTime)
 620            {
 0621                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Exception(SR.Format(SR.ID4255, securityTok
 622            }
 0623        }
 624
 625        /// <summary>
 626        /// Writes the token into a byte array.
 627        /// </summary>
 628        /// <param name="sessionToken">The SessionSecurityToken to write.</param>
 629        /// <exception cref="ArgumentNullException">Thrown if 'sessiontoken' is null.</exception>
 630        /// <returns>An encoded byte array.</returns>
 631        public virtual byte[] WriteToken(SessionSecurityToken sessionToken)
 632        {
 0633            if (sessionToken == null)
 634            {
 0635                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(sessionToken));
 636            }
 637
 0638            using (MemoryStream ms = new MemoryStream())
 639            {
 0640                using (XmlWriter writer = XmlWriter.Create(ms))
 641                {
 0642                    WriteToken(writer, sessionToken);
 0643                    writer.Flush();
 0644                }
 645
 0646                return ms.ToArray();
 647            }
 0648        }
 649
 650        /// <summary>
 651        /// Serializes the given token to the XmlWriter.
 652        /// </summary>
 653        /// <param name="writer">XmlWriter to which the token needs to be serialized</param>
 654        /// <param name=nameof(token)>The SecurityToken to be serialized.</param>
 655        /// <exception cref="ArgumentNullException">The input argument 'writer' is null.</exception>
 656        /// <exception cref="InvalidOperationException">The input argument 'token' is either null or not of type
 657        /// SessionSecurityToken.</exception>
 658        public override void WriteToken(XmlWriter writer, SecurityToken token)
 659        {
 0660            if (writer == null)
 661            {
 0662                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(writer));
 663            }
 664
 0665            if (token == null)
 666            {
 0667                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(token));
 668            }
 669
 0670            if (!(token is SessionSecurityToken sessionToken))
 671            {
 0672                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.ID4
 673            }
 674
 675            string ns, elementName, contextIdElementName, instance;
 676
 0677            if (sessionToken.SecureConversationVersion == WSSecureConversationFeb2005Constants.NamespaceUri)
 678            {
 0679                ns = WSSecureConversationFeb2005Constants.Namespace;
 0680                elementName = WSSecureConversationFeb2005Constants.ElementNames.Name;
 0681                contextIdElementName = WSSecureConversationFeb2005Constants.ElementNames.Identifier;
 0682                instance = WSSecureConversationFeb2005Constants.ElementNames.Instance;
 683            }
 0684            else if (sessionToken.SecureConversationVersion == WSSecureConversation13Constants.NamespaceUri)
 685            {
 0686                ns = WSSecureConversation13Constants.Namespace;
 0687                elementName = WSSecureConversation13Constants.ElementNames.Name;
 0688                contextIdElementName = WSSecureConversation13Constants.ElementNames.Identifier;
 0689                instance = WSSecureConversation13Constants.ElementNames.Instance;
 690            }
 691            else
 692            {
 0693                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.ID4
 694            }
 695
 696            XmlDictionaryWriter dicWriter;
 0697            if (writer is XmlDictionaryWriter)
 698            {
 0699                dicWriter = (XmlDictionaryWriter)writer;
 700            }
 701            else
 702            {
 0703                dicWriter = XmlDictionaryWriter.CreateDictionaryWriter(writer);
 704            }
 705
 0706            dicWriter.WriteStartElement(elementName, ns);
 0707            if (sessionToken.Id != null)
 708            {
 0709                dicWriter.WriteAttributeString(WSUtilityConstants.Attributes.IdAttribute, WSUtilityConstants.NamespaceUR
 710            }
 711
 0712            dicWriter.WriteElementString(contextIdElementName, ns, sessionToken.ContextId.ToString());
 713
 0714            if (sessionToken.KeyGeneration != null)
 715            {
 0716                dicWriter.WriteStartElement(instance, ns);
 0717                dicWriter.WriteValue(sessionToken.KeyGeneration);
 0718                dicWriter.WriteEndElement();
 719            }
 720
 0721            if (!sessionToken.IsReferenceMode)
 722            {
 0723                dicWriter.WriteStartElement(CookieElementName, CookieNamespace);
 0724                byte[] cookie = SerializeSecurityToken(token);
 0725                cookie = ApplyTransforms(cookie, true);
 0726                dicWriter.WriteBase64(cookie, 0, cookie.Length);
 0727                dicWriter.WriteEndElement();
 728            }
 729
 0730            dicWriter.WriteEndElement();
 0731            dicWriter.Flush();
 0732        }
 733
 734        private static byte[] SerializeSecurityToken(SecurityToken token)
 735        {
 0736            if (Environment.Version.Major < 9)
 737            {
 738                // Use the new default which is now DataContractSerialization unless an AppContext.Switch is set to forc
 0739                if (AppContext.TryGetSwitch(s_useBinaryFormatter, out var value) && value)
 740                {
 0741                    return SerializeWithBinaryFormatter();
 742                }
 743
 0744                return SerializeWithDataContractSerializer();
 745            }
 746
 0747            return SerializeWithDataContractSerializer();
 748
 749            byte[] SerializeWithBinaryFormatter()
 750            {
 0751                using MemoryStream ms = new();
 0752                BinaryFormatter formatter = new();
 0753                formatter.Serialize(ms, token);
 0754                return ms.ToArray();
 0755            }
 756
 757            byte[] SerializeWithDataContractSerializer()
 758            {
 0759                using MemoryStream ms = new();
 0760                DataContractSerializer serializer = new(typeof(SecurityToken));
 0761                XmlDictionaryWriter binaryDictionaryWriter = XmlDictionaryWriter.CreateBinaryWriter(ms);
 0762                serializer.WriteObject(binaryDictionaryWriter, token);
 0763                binaryDictionaryWriter.Flush();
 0764                return ms.ToArray();
 0765            }
 766        }
 767
 768        private static SecurityToken DeserializeSecurityToken(byte[] bytes)
 769        {
 0770            if (Environment.Version.Major < 9)
 771            {
 0772                if (AppContext.TryGetSwitch(s_useBinaryFormatter, out bool value) && value)
 773                {
 0774                    return DeserializeWithBinaryFormatter();
 775                }
 776                try
 777                {
 0778                    return DeserializeWithDataContractSerializer();
 779                }
 0780                catch
 781                {
 0782                    return DeserializeWithBinaryFormatter();
 783                }
 784            }
 785
 0786            return DeserializeWithDataContractSerializer();
 787
 788            SecurityToken DeserializeWithDataContractSerializer()
 789            {
 0790                DataContractSerializer serializer = new(typeof(SecurityToken));
 0791                XmlDictionaryReader binaryDictionaryReader = XmlDictionaryReader.CreateBinaryReader(bytes, 0, bytes.Leng
 0792                return serializer.ReadObject(binaryDictionaryReader) as SecurityToken;
 793            }
 794
 795            SecurityToken DeserializeWithBinaryFormatter()
 796            {
 0797                using MemoryStream ms = new(bytes);
 0798                BinaryFormatter formatter = new();
 0799                return formatter.Deserialize(ms) as SecurityToken;
 0800            }
 0801        }
 802    }
 803}

Methods/Properties

.cctor()
.ctor(System.Collections.ObjectModel.ReadOnlyCollection`1<CoreWCF.IdentityModel.CookieTransform>,System.TimeSpan)
.ctor(System.Collections.ObjectModel.ReadOnlyCollection`1<CoreWCF.IdentityModel.CookieTransform>)
GetDefaultCookieTransforms(System.IServiceProvider)
CookieElementName()
CookieNamespace()
ApplyTransforms(System.Byte[],System.Boolean)
CanReadToken(System.Xml.XmlReader)
CanValidateToken()
CanWriteToken()
CreateToken(CoreWCF.IdentityModel.Tokens.SecurityTokenDescriptor)
CreateSessionSecurityToken(System.Security.Claims.ClaimsPrincipal,System.String,System.String,System.DateTime,System.DateTime)
DefaultTokenLifetime()
ReadToken(System.Byte[],CoreWCF.IdentityModel.Selectors.SecurityTokenResolver)
ReadToken(System.Xml.XmlReader)
ReadToken(System.Xml.XmlReader,CoreWCF.IdentityModel.Selectors.SecurityTokenResolver)
TokenLifetime()
TokenLifetime(System.TimeSpan)
CreateBootstrapTokenHandlerCollection()
GetTokenTypeIdentifiers()
TokenType()
Transforms()
SetTransforms(System.Collections.Generic.IEnumerable`1<CoreWCF.IdentityModel.CookieTransform>)
ValidateToken(CoreWCF.IdentityModel.Tokens.SecurityToken)
ValidateToken(CoreWCF.IdentityModel.Tokens.SessionSecurityToken,System.String)
ValidateSession(CoreWCF.IdentityModel.Tokens.SessionSecurityToken)
WriteToken(CoreWCF.IdentityModel.Tokens.SessionSecurityToken)
WriteToken(System.Xml.XmlWriter,CoreWCF.IdentityModel.Tokens.SecurityToken)
SerializeSecurityToken(CoreWCF.IdentityModel.Tokens.SecurityToken)
DeserializeSecurityToken(System.Byte[])