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); } }
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"); }
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; }
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 ); } }
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); }