Example #1
0
 protected override Lifetime GetTokenLifetime(Lifetime requestLifetime)
 {
     var scope = Scope as RequestScope;
     if (scope == null) throw new ApplicationException("No STS request scope found!");
     if (scope.RelyingParty.TokenLifeTime > 0)
     {
         return new Lifetime(DateTime.UtcNow, DateTime.UtcNow.AddMinutes(scope.RelyingParty.TokenLifeTime));
     }
     else
     {
         return base.GetTokenLifetime(requestLifetime);
     }
 }
Example #2
0
        public void call_with_expired_token_to_protected_resource_should_fail_with_440()
        {
            var client = new HttpClient { BaseAddress = ApiUrl };

            Lifetime lt = new Lifetime(DateTime.UtcNow.AddHours(-2), DateTime.UtcNow.AddHours(-1));
            AddAuthHeaderWithCert(client, lifetime: lt);

            var response = client.GetAsync("api/values").Result;

            response.StatusCode.Should().Be((HttpStatusCode)440);

            var responseMessage = response.Content.ReadAsStringAsync().Result;
            responseMessage.Should().Contain("Security token expired exception");
        }
Example #3
0
        public static string CreateJwtToken(AuthenticationTicket data, string issuer, SigningCredentials signingCredentials)
        {
            string audience = issuer;

            // As JWT doesn't have a mechanism of passing metadata about what claim should be the name/subject the JWT handler
            // users the default Name claim type. If the identity has another claim type as the name type we need to 
            // switch it to the DefaultNameClaimType.
            var identity = new ClaimsIdentity(data.Identity);
            if (identity.NameClaimType != ClaimsIdentity.DefaultNameClaimType && !string.IsNullOrWhiteSpace(identity.Name))
            {
                identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, identity.Name));
                identity.RemoveClaim(identity.Claims.First(c => c.Type == identity.NameClaimType));
            }

            // And now do the same for roles.
            List<Claim> roleClaims = identity.Claims.Where(c => c.Type == identity.RoleClaimType).ToList();
            if (identity.RoleClaimType != ClaimsIdentity.DefaultRoleClaimType && roleClaims.Any())
            {
                foreach (var roleClaim in roleClaims)
                {
                    identity.RemoveClaim(roleClaim);
                    identity.AddClaim(new Claim(ClaimsIdentity.DefaultRoleClaimType, roleClaim.Value, roleClaim.ValueType, roleClaim.Issuer, roleClaim.OriginalIssuer));
                }
            }

            identity.AddClaims(new[]
            {
                new Claim("iat", GetEpocTimeStamp()),
                new Claim("jti", Guid.NewGuid().ToString("N"))
            });

            Lifetime lifetime = new Lifetime(null, null);
            if (data.Properties.IssuedUtc != null || data.Properties.ExpiresUtc != null)
            {
                lifetime = new Lifetime(data.Properties.IssuedUtc != null ? (DateTime?)((DateTimeOffset)data.Properties.IssuedUtc).UtcDateTime : null, data.Properties.ExpiresUtc != null ? (DateTime?)((DateTimeOffset)data.Properties.ExpiresUtc).UtcDateTime : null);
            }

            var handler = new JwtSecurityTokenHandler();
            return handler.CreateToken(issuer, audience, identity, lifetime.Created, lifetime.Expires, signingCredentials).RawData;
        }
Example #4
0
        protected override Lifetime GetTokenLifetime(Lifetime requestLifetime)
        {
            var scope = Scope as RequestDetailsScope;
            var rp = scope.RequestDetails.RelyingPartyRegistration;

            if (!scope.RequestDetails.IsKnownRealm || rp.TokenLifeTime == 0)
            {
                return base.GetTokenLifetime(requestLifetime);
            }

            var lifetime = new Lifetime(DateTime.UtcNow, DateTime.UtcNow.AddMinutes(rp.TokenLifeTime));
            return lifetime;
        }
        /// <summary>
        /// Creates the conditions for the assertion.
        /// </summary>
        /// <remarks>
        /// <para>
        /// Generally, conditions should be included in assertions to limit the 
        /// impact of misuse of the assertion. Specifying the NotBefore and 
        /// NotOnOrAfter conditions can limit the period of vulnerability in 
        /// the case of a compromised assertion. The AudienceRestrictionCondition
        /// can be used to explicitly state the intended relying party or parties
        /// of the assertion, which coupled with appropriate audience restriction
        /// enforcement at relying parties can help to mitigate spoofing attacks
        /// between relying parties.
        /// </para>
        /// <para>
        /// The default implementation creates NotBefore and NotOnOrAfter conditions
        /// based on the tokenDescriptor.Lifetime. It will also generate an 
        /// AudienceRestrictionCondition limiting consumption of the assertion to 
        /// tokenDescriptor.Scope.Address.
        /// </para>
        /// </remarks>
        /// <param name="tokenLifetime">Lifetime of the Token.</param>
        /// <param name="relyingPartyAddress">The endpoint address to who the token is created. The address
        /// is modeled as an AudienceRestriction condition.</param>
        /// <param name="tokenDescriptor">The token descriptor.</param>
        /// <returns>A Saml2Conditions object.</returns>
        protected virtual Saml2Conditions CreateConditions(Lifetime tokenLifetime, string relyingPartyAddress, SecurityTokenDescriptor tokenDescriptor)
        {
            bool hasLifetime = null != tokenLifetime;
            bool hasScope = !string.IsNullOrEmpty(relyingPartyAddress);
            if (!hasLifetime && !hasScope)
            {
                return null;
            }

            Saml2Conditions conditions = new Saml2Conditions();
            if (hasLifetime)
            {
                conditions.NotBefore = tokenLifetime.Created;
                conditions.NotOnOrAfter = tokenLifetime.Expires;
            }

            if (hasScope)
            {
                conditions.AudienceRestrictions.Add(new Saml2AudienceRestriction(new Uri(relyingPartyAddress)));
            }

            return conditions;
        }
        public static void WriteLifetime(XmlWriter writer, Lifetime lifetime, WSTrustConstantsAdapter trustConstants)
        {
            if (writer == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
            }

            if (lifetime == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("lifetime");
            }

            if (trustConstants == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("trustConstants");
            }

            writer.WriteStartElement(trustConstants.Prefix, trustConstants.Elements.Lifetime, trustConstants.NamespaceURI);

            if (lifetime.Created != null)
            {
                writer.WriteElementString(WSUtilityConstants.Prefix, WSUtilityConstants.ElementNames.Created, WSUtilityConstants.NamespaceURI, lifetime.Created.Value.ToString(DateTimeFormats.Generated, CultureInfo.InvariantCulture));
            }

            if (lifetime.Expires != null)
            {
                writer.WriteElementString(WSUtilityConstants.Prefix, WSUtilityConstants.ElementNames.Expires, WSUtilityConstants.NamespaceURI, lifetime.Expires.Value.ToString(DateTimeFormats.Generated, CultureInfo.InvariantCulture));
            }

            writer.WriteEndElement();
        }
        public static Lifetime ReadLifetime(XmlReader reader, WSTrustConstantsAdapter trustConstants)
        {
            if (reader == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
            }

            if (trustConstants == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("trustConstants");
            }

            DateTime? created = null;
            DateTime? expires = null;
            Lifetime lifetime = null;
            bool isEmptyElement = reader.IsEmptyElement;
            reader.ReadStartElement();

            if (!isEmptyElement)
            {
                if (reader.IsStartElement(WSUtilityConstants.ElementNames.Created, WSUtilityConstants.NamespaceURI))
                {
                    reader.ReadStartElement(WSUtilityConstants.ElementNames.Created, WSUtilityConstants.NamespaceURI);
                    created = DateTime.ParseExact(reader.ReadString(), DateTimeFormats.Accepted, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None).ToUniversalTime();
                    reader.ReadEndElement();
                }

                if (reader.IsStartElement(WSUtilityConstants.ElementNames.Expires, WSUtilityConstants.NamespaceURI))
                {
                    reader.ReadStartElement(WSUtilityConstants.ElementNames.Expires, WSUtilityConstants.NamespaceURI);
                    expires = DateTime.ParseExact(reader.ReadString(), DateTimeFormats.Accepted, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None).ToUniversalTime();
                    reader.ReadEndElement();
                }

                reader.ReadEndElement();

                lifetime = new Lifetime(created, expires);
            }

            if (lifetime == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new WSTrustSerializationException(SR.GetString(SR.ID3161)));
            }

            return lifetime;
        }
        /// <summary>
        /// Gets the lifetime of the issued token.
        /// Normally called with the lifetime that arrived in the RST.  
        /// The algorithm for calculating the token lifetime is:
        /// requestLifeTime (in)            LifeTime (returned)
        /// Created     Expires             Created             Expires
        /// null        null                DateTime.UtcNow     DateTime.UtcNow + SecurityTokenServiceConfiguration.DefaultTokenLifetime
        /// C           null                C                   C + SecurityTokenServiceConfiguration.DefaultTokenLifetime
        /// null        E                   DateTime.UtcNow     E
        /// C           E                   C                   E
        /// </summary>
        /// <param name="requestLifetime">The requestor's desired life time.</param>
        protected virtual Lifetime GetTokenLifetime(Lifetime requestLifetime)
        {
            DateTime created;
            DateTime expires;

            if (requestLifetime == null)
            {
                created = DateTime.UtcNow;
                expires = DateTimeUtil.Add(created, _securityTokenServiceConfiguration.DefaultTokenLifetime);
            }
            else
            {
                if (requestLifetime.Created.HasValue)
                {
                    created = requestLifetime.Created.Value;
                }
                else
                {
                    created = DateTime.UtcNow;
                }

                if (requestLifetime.Expires.HasValue)
                {
                    expires = requestLifetime.Expires.Value;
                }
                else
                {
                    expires = DateTimeUtil.Add(created, _securityTokenServiceConfiguration.DefaultTokenLifetime);
                }
            }

            VerifyComputedLifetime(created, expires);

            return new Lifetime(created, expires);
        }
 protected override Lifetime GetTokenLifetime(Lifetime requestLifetime)
 {
     if (requestLifetime != null)
     {
         return requestLifetime;
     }
     var lifeTime = new Lifetime(DateTime.Now, DateTime.Now.AddMinutes(30));
     return lifeTime;
 }
        /// <summary>
        /// Generates all the conditions for saml
        /// 
        /// 1. Lifetime condition
        /// 2. AudienceRestriction condition
        /// 
        /// </summary>
        /// <param name="tokenLifetime">Lifetime of the Token.</param>
        /// <param name="relyingPartyAddress">The endpoint address to who the token is created. The address
        /// is modelled as an AudienceRestriction condition.</param>
        /// <param name="tokenDescriptor">Contains all the other information that is used in token issuance.</param>
        /// <returns>SamlConditions</returns>
        protected virtual SamlConditions CreateConditions(Lifetime tokenLifetime, string relyingPartyAddress, SecurityTokenDescriptor tokenDescriptor)
        {
            SamlConditions conditions = new SamlConditions();
            if (tokenLifetime != null)
            {
                if (tokenLifetime.Created != null)
                {
                    conditions.NotBefore = tokenLifetime.Created.Value;
                }

                if (tokenLifetime.Expires != null)
                {
                    conditions.NotOnOrAfter = tokenLifetime.Expires.Value;
                }
            }

            if (!string.IsNullOrEmpty(relyingPartyAddress))
            {
                conditions.Conditions.Add(new SamlAudienceRestrictionCondition(new Uri[] { new Uri(relyingPartyAddress) }));
            }

            return conditions;
        }
        public static IEnumerable<Claim> ClaimsPlus( IEnumerable<Claim> claims = null, SigningCredentials signingCredential = null, Lifetime lifetime = null, string issuer = null, string originalIssuer = null, string audience = null )
        {
            string thisIssuer = issuer ?? ClaimsIdentity.DefaultIssuer;
            string thisOriginalIssuer = originalIssuer ?? thisIssuer;

            if ( claims != null )
            {
                foreach ( Claim claim in claims ) yield return claim;
            }

            if ( signingCredential != null )
            {
                JwtHeader header = new JwtHeader( signingCredential );

                foreach ( string key in header.Keys )
                {
                    string value = header[key];
                    yield return new Claim( key, value, ClaimValueTypes.String, thisIssuer, thisOriginalIssuer );
                }
            }

            if ( lifetime != null )
            {
                yield return new Claim( JwtRegisteredClaimNames.Nbf, EpochTime.GetIntDate(lifetime.Created.Value ).ToString(), ClaimValueTypes.String, thisIssuer, thisOriginalIssuer );
                yield return new Claim( JwtRegisteredClaimNames.Exp, EpochTime.GetIntDate( lifetime.Expires.Value ).ToString(), ClaimValueTypes.String, thisIssuer, thisOriginalIssuer );
            }

            if ( audience != null )
            {
                yield return new Claim( JwtRegisteredClaimNames.Aud, audience, ClaimValueTypes.String, thisIssuer, thisOriginalIssuer );
            }

            if ( issuer != null )
            {
                yield return new Claim( JwtRegisteredClaimNames.Iss, issuer, ClaimValueTypes.String, thisIssuer, thisOriginalIssuer );
            }
        }
Example #12
0
        private void AddAuthHeaderWithCert(HttpClient client, string audience = "http://www.example.com", Lifetime lifetime = null)
        {
            var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
            store.Open(OpenFlags.ReadOnly);

            var signingCert = store.Certificates
                .Cast<X509Certificate2>()
                .FirstOrDefault(certificate => certificate.Subject == CertificateSubjectName);

            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new[]
                {
                    new Claim(ClaimTypes.Name, "bsmith"),
                    new Claim(ClaimTypes.GivenName, "Bob"),
                    new Claim(ClaimTypes.Surname, "Smith"),
                    new Claim(ClaimTypes.Role, "Customer Service")
                }),
                TokenIssuerName = "corp",
                AppliesToAddress = audience,
                SigningCredentials = new X509SigningCredentials(signingCert)
            };

            if (lifetime != null)
            {
                tokenDescriptor.Lifetime = lifetime;
            }

            var tokenHandler = new JwtSecurityTokenHandler();
            var token = tokenHandler.CreateToken(tokenDescriptor);
            var tokenString = tokenHandler.WriteToken(token);

            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenString);
        }