public SamlResponse Create(ISaml2pServiceProvider partner, Status status, string authnRequestId = null, string relayState = null, Saml2SecurityToken token = null) { var destination = new Uri(partner.BaseUrl, partner.AssertionConsumerServiceEndpoint); if (token != null) { if (authnRequestId != null) { token.SetRecipient(destination, authnRequestId); } else { token.SetRecipient(destination); } token.SetNotOnOrAfter(); } var response = new SamlResponse { Id = $"_{Guid.NewGuid()}", // TODO: create id factory SecurityToken = token, Destination = destination, IssueInstant = token?.Assertion.IssueInstant, Issuer = partner.ExpectedIssuer ?? _options.DefaultIssuer, Status = status, InResponseTo = authnRequestId, RelayState = relayState }; return(response); }
public static async ValueTask InvokeAsync(Saml2pOptions options, ISaml2pServiceProvider sp, Func <Saml2pIdentityProviderEvents, ValueTask> method) { await method(options.IdentityProviderEvents); if (sp?.Events != null) { await method(sp.Events); } }
private SigningCredentials GetSigningCredentials(ISaml2pServiceProvider partner) { if (partner.AssertionSigningKey == null) { throw new ArgumentNullException(nameof(partner.AssertionSigningKey)); } if (partner.AssertionSigningMethod == null) { throw new ArgumentNullException(nameof(partner.AssertionSigningMethod)); } var credentials = partner.AssertionSigningMethod.CreateCredentials(partner.AssertionSigningKey); Trace("Signing credentials created.", credentials); return(credentials); }
private EncryptingCredentials GetEncryptingCredentials(ISaml2pServiceProvider partner) { if (!partner.RequiresEncryptedAssertion) { return(null); } if (partner.AssertionEncryptionKey == null) { throw new ArgumentNullException(nameof(partner.AssertionEncryptionKey)); } if (partner.AssertionEncryptionMethod == null) { throw new ArgumentNullException(nameof(partner.AssertionEncryptionMethod)); } var credentials = partner.AssertionEncryptionMethod.CreateCredentials(partner.AssertionEncryptionKey); Trace("Encrypting credentials created.", credentials); return(credentials); }
public SamlResponse Create(ISaml2pServiceProvider partner, string authnRequestId = null, string relayState = null, SamlResponseStatus status = SamlResponseStatus.Success, SamlResponseStatus?subStatus = null, Saml2SecurityToken token = null) => Create(partner, status.ToStatus(subStatus), authnRequestId: authnRequestId, relayState: relayState, token: token);
public async ValueTask <SecurityTokenDescriptor> CreateSecurityTokenDescriptorAsync(ClaimsIdentity identity, ISaml2pServiceProvider partner) { var instant = identity.FindFirst(ClaimTypes.AuthenticationInstant)?.Value; var issuedAt = _systemClock.UtcNow.DateTime; if (instant != null && DateTime.TryParse(instant, out var parsed)) { issuedAt = parsed; } var issuer = partner.ExpectedIssuer ?? _options.DefaultIssuer; var lifetime = partner.TokenLifeTime ?? _options.DefaultTokenLifetime; var tolerence = partner.MaxClockSkew ?? _options.DefaultMaxClockSkew ?? TimeSpan.Zero; var claims = new List <Claim>(); foreach (var provider in _claimsProviders) { if (await provider.CanGenerateClaimsAsync(partner)) { _logger.LogInformation($"Generating claims using {provider.GetType().Name}."); var generated = await provider.GenerateClaimsAsync(identity, partner, issuer); Trace($"Generated claims from {provider.GetType().Name}.", generated); claims.AddRange(generated); } } var defaults = new[] { ClaimTypes.NameIdentifier, ClaimTypes.AuthenticationInstant, ClaimTypes.AuthenticationMethod }; var required = (partner.RequiredClaims ?? Enumerable.Empty <string>()).Distinct(); var optional = (partner.OptionalClaims ?? Enumerable.Empty <string>()).Distinct(); var supported = defaults.Concat(required).Concat(optional).Distinct(); Debug("Checking for all required claims. Required claim types:", required); if (required.Except(claims.Select(c => c.Type)).Any()) { throw new SecurityException("Unable to generate all required claims."); } Debug("Filtering generated claims. Supported claim types:", supported); claims = claims.Where(c => supported.Contains(c.Type)).ToList(); Trace($"Filtered claims.", claims); AddRequiredClaims(identity, claims, issuedAt, issuer); var attributes = claims .Where(c => c.Type != ClaimTypes.NameIdentifier) .Where(c => c.Type != ClaimTypes.AuthenticationInstant) .Where(c => c.Type != ClaimTypes.AuthenticationMethod) ; if (!attributes.Any()) { claims.Add(new Claim("http://schemas.solidsoft.works/ws/2020/08/identity/claims/null", bool.TrueString, ClaimValueTypes.Boolean, issuer)); } foreach (var attribute in attributes) { if (attribute.Properties.ContainsKey(ClaimProperties.SamlAttributeNameFormat)) { continue; } attribute.Properties.Add(ClaimProperties.SamlAttributeNameFormat, "urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"); } var expires = issuedAt .Add(lifetime) .Add(tolerence) ; var descriptor = new SecurityTokenDescriptor { Audience = partner.Id, Subject = new ClaimsIdentity(claims, "SSO"), Issuer = issuer, IssuedAt = issuedAt, NotBefore = issuedAt.Subtract(tolerence), Expires = expires, SigningCredentials = GetSigningCredentials(partner), EncryptingCredentials = GetEncryptingCredentials(partner) }; return(descriptor); }
public ValueTask <IEnumerable <Claim> > GenerateClaimsAsync(ClaimsIdentity identity, ISaml2pServiceProvider _, string __) => new ValueTask <IEnumerable <Claim> >(identity.Claims);
public ValueTask <bool> CanGenerateClaimsAsync(ISaml2pServiceProvider partner) => new ValueTask <bool>(partner.AllowClaimsPassthrough);