コード例 #1
0
        private static Saml2NameIdentifier ProcessLogoutNameIdentifier(Claim claim)
        {
            var fields = DelimitedString.Split(claim.Value);

            var saml2NameIdentifier = new Saml2NameIdentifier(fields[4]);

            if (!string.IsNullOrEmpty(fields[0]))
            {
                saml2NameIdentifier.NameQualifier = fields[0];
            }
            if (!string.IsNullOrEmpty(fields[1]))
            {
                saml2NameIdentifier.SPNameQualifier = fields[1];
            }
            if (!string.IsNullOrEmpty(fields[2]))
            {
                saml2NameIdentifier.Format = new Uri(fields[2]);
            }
            if (!string.IsNullOrEmpty(fields[3]))
            {
                saml2NameIdentifier.SPProvidedId = fields[3];
            }

            return(saml2NameIdentifier);
        }
コード例 #2
0
        public void ShouldWriterSamlResponseAssertionElement()
        {
            var issuer    = new Saml2NameIdentifier("issuer");
            var assertion = new Saml2Assertion(issuer)
            {
                Subject = new Saml2Subject(new Saml2NameIdentifier("subject"))
            };

            var token = new Saml2SecurityToken(assertion);

            var response = new SamlResponse
            {
                SecurityToken = token
            };

            var serialized = _serializer.SerializeSamlResponse(response);

            Assert.NotNull(serialized);

            var doc  = XDocument.Parse(serialized);
            var root = doc.Root;

            _mockHandler.Verify(h => h.WriteToken(It.IsAny <XmlWriter>(), token), Times.Once());
            var element = root.Element(XName.Get("Assertion", _assertionNamespace));

            Assert.NotNull(element);
        }
コード例 #3
0
        private static Saml2Assertion CreatePlaceholderAssertion()
        {
            var issuer    = new Saml2NameIdentifier("__encrypted__");
            var assertion = new Saml2Assertion(issuer);

            return(assertion);
        }
コード例 #4
0
 public SamlLogoutContext(Uri reason, Saml2NameIdentifier nameId, string federationPartyId, params string[] sessionIndex)
 {
     this.Reason            = reason;
     this.NameId            = nameId;
     this.FederationPartyId = federationPartyId;
     this.SessionIndex      = sessionIndex;
 }
コード例 #5
0
        private Saml2Assertion CreateSamlAssertion(SecurityKey signatureKey, SecurityKeyIdentifier signatureKeyIdentifier, SecurityKeyIdentifier proofKeyIdentifier)
        {
            Claim claim = base.ClientCredentials.Claims.FirstOrDefault((Claim c) => c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier");

            if (claim == null)
            {
                throw new ArgumentException("At least one NameIdentifier/Identity claim must be present in the claimset", "ClaimsClientCredentials.Claims");
            }
            Saml2Subject saml2Subject = new Saml2Subject
            {
                NameId = new Saml2NameIdentifier(claim.Value, new Uri("urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"))
            };
            Saml2SubjectConfirmationData saml2SubjectConfirmationData = new Saml2SubjectConfirmationData();

            saml2SubjectConfirmationData.KeyIdentifiers.Add(proofKeyIdentifier);
            saml2Subject.SubjectConfirmations.Add(new Saml2SubjectConfirmation(new Uri("urn:oasis:names:tc:SAML:2.0:cm:holder-of-key"), saml2SubjectConfirmationData));
            IEnumerable <Saml2Attribute> enumerable = from c in base.ClientCredentials.Claims.Except(new Claim[]
            {
                claim
            })
                                                      select new Saml2Attribute(c.Type, c.Value);
            Claim claim2 = base.ClientCredentials.Claims.FirstOrDefault((Claim c) => c.Type == "http://www.tridion.com/2009/08/directoryservice/claims/directoryServiceName");
            Saml2NameIdentifier issuer;

            if (claim2 == null)
            {
                Saml2Attribute saml2Attribute = new Saml2Attribute("http://www.tridion.com/2009/08/directoryservice/claims/directoryServiceName", claim.Issuer);
                enumerable = enumerable.Concat(new Saml2Attribute[]
                {
                    saml2Attribute
                });
                issuer = new Saml2NameIdentifier(claim.Issuer);
            }
            else
            {
                issuer = new Saml2NameIdentifier(claim2.Value);
            }
            DateTime       utcNow         = DateTime.UtcNow;
            Saml2Assertion saml2Assertion = new Saml2Assertion(issuer)
            {
                Subject      = saml2Subject,
                IssueInstant = utcNow,
                Conditions   = new Saml2Conditions
                {
                    NotBefore    = new DateTime?(utcNow),
                    NotOnOrAfter = new DateTime?(utcNow + base.TokenValidityTimeSpan)
                },
                Advice             = new Saml2Advice(),
                SigningCredentials = new SigningCredentials(signatureKey, base.SecurityAlgorithmSuite.DefaultAsymmetricSignatureAlgorithm, base.SecurityAlgorithmSuite.DefaultDigestAlgorithm, signatureKeyIdentifier)
            };

            saml2Assertion.Statements.Add(new Saml2AttributeStatement(enumerable));
            if (base.ClientCredentials.AudienceUris != null)
            {
                saml2Assertion.Conditions.AudienceRestrictions.Add(new Saml2AudienceRestriction(base.ClientCredentials.AudienceUris));
            }
            return(saml2Assertion);
        }
コード例 #6
0
 public Saml2LogoutRequest(Saml2Configuration config, ClaimsPrincipal currentPrincipal) : this(config)
 {
     var identity = currentPrincipal.Identities.First();
     if (identity.IsAuthenticated)
     {
         NameId       = new Saml2NameIdentifier(ReadClaimValue(identity, Saml2ClaimTypes.NameId), new Uri(ReadClaimValue(identity, Saml2ClaimTypes.NameIdFormat)));
         SessionIndex = ReadClaimValue(identity, Saml2ClaimTypes.SessionIndex);
     }
 }
コード例 #7
0
        public void ClaimsExtensions_ToSaml2NameIdentifier_LogoutNameIdentifier_NameOnly()
        {
            var claim = new Claim(Saml2ClaimTypes.LogoutNameIdentifier, ",,,,NameId");

            var actual = claim.ToSaml2NameIdentifier();

            var expected = new Saml2NameIdentifier("NameId");

            actual.Should().BeEquivalentTo(expected);
        }
コード例 #8
0
        public Saml2LogoutRequest()
        {
            NotOnOrAfter = DateTime.UtcNow.AddMinutes(10);

            var identity = ClaimsPrincipal.Current.Identities.First();

            if (identity.IsAuthenticated)
            {
                NameId       = new Saml2NameIdentifier(ReadClaimValue(identity, Saml2ClaimTypes.NameId), new Uri(ReadClaimValue(identity, Saml2ClaimTypes.NameIdFormat)));
                SessionIndex = ReadClaimValue(identity, Saml2ClaimTypes.SessionIndex);
            }
        }
コード例 #9
0
        private string GetTokenString(string organizationName, bool isServiceBusScope)
        {
            // Generate Saml assertions..
            string issuerName = DefaultIssuer;
            //string issuerName = "localhost";

            Saml2NameIdentifier saml2NameIdentifier = new Saml2NameIdentifier(issuerName);             // this is the issuer name.
            Saml2Assertion      saml2Assertion      = new Saml2Assertion(saml2NameIdentifier);

            Uri acsScope = new Uri(StsPath(solutionName, isServiceBusScope));

            saml2Assertion.Conditions = new Saml2Conditions();
            saml2Assertion.Conditions
            .AudienceRestrictions.Add(new Saml2AudienceRestriction(acsScope));           // this is the ACS uri.

            saml2Assertion.Conditions.NotOnOrAfter = DateTime.Now.AddDays(1);            // Should this be utc?
            saml2Assertion.Conditions.NotBefore    = DateTime.Now.AddHours(-1);          // should this be utc?

            string certName = "localhost";

            X509Certificate2 localCert = RetrieveCertificate(certName);

            if (!localCert.HasPrivateKey)
            {
                throw new ArgumentException("Cert should have private key.", "certificate");
            }

            saml2Assertion.SigningCredentials = new X509SigningCredentials(localCert);             // this cert should have the private keys.

            // Add claim assertions.
            saml2Assertion.Statements.Add(
                new Saml2AttributeStatement(
                    new Saml2Attribute(OrganizationClaimType, organizationName)));

            // the submitter should always be a bearer.
            saml2Assertion.Subject = new Saml2Subject(new Saml2SubjectConfirmation(Saml2Constants.ConfirmationMethods.Bearer));

            // Wrap it into a security token.
            SecurityTokenHandler tokenHandler  = new Saml2SecurityTokenHandler();
            SecurityToken        securityToken = new Saml2SecurityToken(saml2Assertion);

            // Serialize the security token.
            StringBuilder sb = new StringBuilder();

            using (XmlWriter writer = XmlTextWriter.Create(new StringWriter(sb, CultureInfo.InvariantCulture)))
            {
                tokenHandler.WriteToken(writer, securityToken);
                writer.Close();
            }

            return(sb.ToString());
        }
コード例 #10
0
        private Saml2Subject GetSaml2Subject(XmlDocument xmlDocument)
        {
            XmlNamespaceManager nsManager = new XmlNamespaceManager(xmlDocument.NameTable);

            nsManager.AddNamespace("saml2", "urn:oasis:names:tc:SAML:2.0:assertion");

            XmlNode subjectNode = xmlDocument.SelectSingleNode("//saml2:Subject", nsManager);
            XmlNode nameIDNode  = subjectNode.SelectSingleNode("//saml2:NameID", nsManager);

            Saml2NameIdentifier nameId = new Saml2NameIdentifier(nameIDNode.InnerText, new Uri(nameIDNode.Attributes["Format"].Value));

            return(new Saml2Subject(nameId));
        }
コード例 #11
0
        public void ClaimsExtensions_ToSaml2NameIdentifier_LogoutNameIdentifier_SPProvidedId()
        {
            var claim = new Claim(Saml2ClaimTypes.LogoutNameIdentifier, ",,,spId,NameId");

            var actual = claim.ToSaml2NameIdentifier();

            var expected = new Saml2NameIdentifier("NameId")
            {
                SPProvidedId = "spId"
            };

            actual.Should().BeEquivalentTo(expected);
        }
コード例 #12
0
        public void ClaimsExtensions_ToSaml2NameIdentifier_LogoutNameIdentifier_NameIdFormat()
        {
            var claim = new Claim(Saml2ClaimTypes.LogoutNameIdentifier, ",,urn:foo,,NameId");

            var actual = claim.ToSaml2NameIdentifier();

            var expected = new Saml2NameIdentifier("NameId")
            {
                Format = new Uri("urn:foo")
            };

            actual.Should().BeEquivalentTo(expected);
        }
コード例 #13
0
        public void ClaimsExtensions_ToSaml2NameIdentifier_LogoutNameIdentifier_SPNameQualifier()
        {
            var claim = new Claim(AuthServicesClaimTypes.LogoutNameIdentifier, ",qualifier,,,NameId");

            var actual = claim.ToSaml2NameIdentifier();

            var expected = new Saml2NameIdentifier("NameId")
            {
                SPNameQualifier = "qualifier"
            };

            actual.ShouldBeEquivalentTo(expected);
        }
コード例 #14
0
        private static IEnumerable <Claim> ClaimsFromSubject(Saml2Subject subject, Saml2NameIdentifier issuer)
        {
            if (subject == null)
            {
                yield break;
            }
            if (subject.NameId != null)
            {
                yield return(new Claim("sub", subject.NameId.Value, ClaimValueTypes.String, issuer.Value));                     // openid connect

                yield return(new Claim(ClaimTypes.NameIdentifier, subject.NameId.Value, ClaimValueTypes.String, issuer.Value)); // saml
            }
        }
コード例 #15
0
        public void ClaimsExtensions_ToSaml2NameIdentifier_NameIdentifier_SPProvidedId()
        {
            var claim = new Claim(ClaimTypes.NameIdentifier, "NameId");

            claim.Properties[ClaimProperties.SamlNameIdentifierSPProvidedId] = "spId";

            var actual = claim.ToSaml2NameIdentifier();

            var expected = new Saml2NameIdentifier("NameId")
            {
                SPProvidedId = "spId"
            };

            actual.Should().BeEquivalentTo(expected);
        }
コード例 #16
0
        public void ClaimsExtensions_ToSaml2NameIdentifier_NameIdentifier_NameQualifier()
        {
            var claim = new Claim(ClaimTypes.NameIdentifier, "NameId");

            claim.Properties[ClaimProperties.SamlNameIdentifierNameQualifier] = "qualifier";

            var actual = claim.ToSaml2NameIdentifier();

            var expected = new Saml2NameIdentifier("NameId")
            {
                NameQualifier = "qualifier"
            };

            actual.Should().BeEquivalentTo(expected);
        }
コード例 #17
0
        public void ClaimsExtensions_ToSaml2NameIdentifier_NameIdentifier_NameIdFormat()
        {
            var claim = new Claim(ClaimTypes.NameIdentifier, "NameId");

            claim.Properties[ClaimProperties.SamlNameIdentifierFormat] = "urn:foo";

            var actual = claim.ToSaml2NameIdentifier();

            var expected = new Saml2NameIdentifier("NameId")
            {
                Format = new Uri("urn:foo")
            };

            actual.Should().BeEquivalentTo(expected);
        }
コード例 #18
0
        public static SecurityToken MakeBootstrapSecurityToken()
        {
            Saml2NameIdentifier identifier = new Saml2NameIdentifier("http://localhost/Echo");

            Saml2Assertion assertion = new Saml2Assertion(identifier);

            assertion.Issuer  = new Saml2NameIdentifier("idp1.test.oio.dk");
            assertion.Subject = new Saml2Subject(new Saml2NameIdentifier("Casper", new Uri("urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified")));
            Saml2Attribute atribute = new Saml2Attribute("dk:gov:saml:attribute:AssuranceLevel", "2");

            atribute.NameFormat = new Uri("urn:oasis:names:tc:SAML:2.0:attrname-format:basic");

            assertion.Statements.Add(new Saml2AttributeStatement(atribute));
            return(new Saml2SecurityToken(assertion));
        }
コード例 #19
0
        private static Saml2NameIdentifier ProcessNameIdentifier(Claim claim)
        {
            var saml2NameIdentifier = new Saml2NameIdentifier(claim.Value);

            claim.ExtractProperty(ClaimProperties.SamlNameIdentifierFormat,
                                  value => saml2NameIdentifier.Format = new Uri(value));
            claim.ExtractProperty(ClaimProperties.SamlNameIdentifierNameQualifier,
                                  value => saml2NameIdentifier.NameQualifier = value);
            claim.ExtractProperty(ClaimProperties.SamlNameIdentifierSPNameQualifier,
                                  value => saml2NameIdentifier.SPNameQualifier = value);
            claim.ExtractProperty(ClaimProperties.SamlNameIdentifierSPProvidedId,
                                  value => saml2NameIdentifier.SPProvidedId = value);

            return(saml2NameIdentifier);
        }
コード例 #20
0
        /// <summary>
        /// Create XElement for the Saml2NameIdentifier.
        /// </summary>
        /// <param name="nameIdentifier"></param>
        /// <returns></returns>
        public static XElement ToXElement(this Saml2NameIdentifier nameIdentifier)
        {
            if (nameIdentifier == null)
            {
                throw new ArgumentNullException("nameIdentifier");
            }

            var nameIdElement = new XElement(Saml2Namespaces.Saml2 + "NameID",
                                             nameIdentifier.Value);

            nameIdElement.AddAttributeIfNotNullOrEmpty("Format", nameIdentifier.Format);
            nameIdElement.AddAttributeIfNotNullOrEmpty("NameQualifier", nameIdentifier.NameQualifier);
            nameIdElement.AddAttributeIfNotNullOrEmpty("SPNameQualifier", nameIdentifier.SPNameQualifier);
            nameIdElement.AddAttributeIfNotNullOrEmpty("SPProvidedID", nameIdentifier.SPProvidedId);

            return(nameIdElement);
        }
コード例 #21
0
 public Saml2LogoutRequest(Saml2Configuration config, ClaimsPrincipal currentPrincipal) : this(config)
 {
     var identity = currentPrincipal.Identities.First();
     if (identity.IsAuthenticated)
     {
         var nameIdFormat = ReadClaimValue(identity, Saml2ClaimTypes.NameIdFormat, false);
         if (string.IsNullOrEmpty(nameIdFormat))
         {
             NameId = new Saml2NameIdentifier(ReadClaimValue(identity, Saml2ClaimTypes.NameId));
         }
         else
         {
             NameId = new Saml2NameIdentifier(ReadClaimValue(identity, Saml2ClaimTypes.NameId), new Uri(nameIdFormat));
         }
         SessionIndex = ReadClaimValue(identity, Saml2ClaimTypes.SessionIndex, false);
     }
 }
コード例 #22
0
        public void IdentityProvider_CreateLogoutRequest()
        {
            var options = StubFactory.CreateOptions();

            options.SPOptions.ServiceCertificates.Add(new ServiceCertificate()
            {
                Certificate = SignedXmlHelper.TestCert
            });

            var subject = options.IdentityProviders[0];

            var nameIdClaim = new Claim(ClaimTypes.NameIdentifier, "NameId", null, subject.EntityId.Id);

            nameIdClaim.Properties[ClaimProperties.SamlNameIdentifierFormat] = "urn:nameIdFormat";

            Thread.CurrentPrincipal = new ClaimsPrincipal(new ClaimsIdentity(
                                                              new Claim[]
            {
                nameIdClaim,
                new Claim(AuthServicesClaimTypes.SessionIndex, "SessionId", null, subject.EntityId.Id)
            }, "Federation"));

            // Grab a datetime both before and after creation to handle case
            // when the second part is changed during excecution of the test.
            // We're assuming that the creation does not take more than a
            // second, so two values will do.
            var beforeTime = DateTime.UtcNow.ToSaml2DateTimeString();
            var actual     = subject.CreateLogoutRequest();
            var aftertime  = DateTime.UtcNow.ToSaml2DateTimeString();

            actual.Issuer.Id.Should().Be(options.SPOptions.EntityId.Id);
            actual.Id.Value.Should().NotBeEmpty();
            actual.IssueInstant.Should().Match(i => i == beforeTime || i == aftertime);
            actual.SessionIndex.Should().Be("SessionId");
            actual.SigningCertificate.Thumbprint.Should().Be(SignedXmlHelper.TestCert.Thumbprint);

            var expectedNameId = new Saml2NameIdentifier("NameId")
            {
                Format = new Uri("urn:nameIdFormat")
            };

            actual.NameId.ShouldBeEquivalentTo(expectedNameId);
        }
コード例 #23
0
        /// <summary>
        /// Create a Saml2NameIdentifier from a NameIdentifier claim.
        /// </summary>
        /// <param name="nameIdClaim">Name identifier claim.</param>
        /// <returns>Saml2NameIdentifier</returns>
        public static Saml2NameIdentifier ToSaml2NameIdentifier(this Claim nameIdClaim)
        {
            if (nameIdClaim == null)
            {
                throw new ArgumentNullException(nameof(nameIdClaim));
            }

            var saml2NameIdentifier = new Saml2NameIdentifier(nameIdClaim.Value);

            nameIdClaim.ExtractProperty(ClaimProperties.SamlNameIdentifierFormat,
                                        value => saml2NameIdentifier.Format = new Uri(value));
            nameIdClaim.ExtractProperty(ClaimProperties.SamlNameIdentifierNameQualifier,
                                        value => saml2NameIdentifier.NameQualifier = value);
            nameIdClaim.ExtractProperty(ClaimProperties.SamlNameIdentifierSPNameQualifier,
                                        value => saml2NameIdentifier.SPNameQualifier = value);
            nameIdClaim.ExtractProperty(ClaimProperties.SamlNameIdentifierSPProvidedId,
                                        value => saml2NameIdentifier.SPProvidedId = value);

            return(saml2NameIdentifier);
        }
コード例 #24
0
        /// <summary>
        /// Creates the SAML authentication request with the correct name identifier.
        /// </summary>
        /// <param name="identityClaim">The identity claim.</param>
        /// <param name="authnRequestId">The AuthnRequest identifier.</param>
        /// <param name="ascUri">The asc URI.</param>
        /// <returns>The authentication request.</returns>
        public static Saml2AuthenticationSecondFactorRequest CreateAuthnRequest(Claim identityClaim, string authnRequestId, Uri ascUri)
        {
            var serviceproviderConfiguration = Kentor.AuthServices.Configuration.Options.FromConfiguration;

            Log.DebugFormat("Creating AuthnRequest for identity '{0}'", identityClaim.Value);
            var nameIdentifier = new Saml2NameIdentifier(GetNameId(identityClaim), new Uri("urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"));

            var authnRequest = new Saml2AuthenticationSecondFactorRequest
            {
                DestinationUrl = Settings.Default.SecondFactorEndpoint,
                AssertionConsumerServiceUrl = ascUri,
                Issuer = serviceproviderConfiguration.SPOptions.EntityId,
                RequestedAuthnContext = new Saml2RequestedAuthnContext(Settings.Default.MinimalLoa, AuthnContextComparisonType.Exact),
                Subject = new Saml2Subject(nameIdentifier),
            };

            authnRequest.SetId(authnRequestId);

            Log.InfoFormat("Created AuthnRequest for '{0}' with id '{1}'", identityClaim.Value, authnRequest.Id.Value);
            return(authnRequest);
        }
コード例 #25
0
        private async Task <Saml2SecurityToken> CreateSecurityTokenAsync(SignInRequest request, RelyingParty rp, ClaimsIdentity outgoingSubject)
        {
            var now = DateTime.Now;

            var outgoingNameId = outgoingSubject.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier);

            if (outgoingNameId == null)
            {
                _logger.LogError("The user profile does not have a name id");

                throw new SignInException("The user profile does not have a name id");
            }

            var issuer = new Saml2NameIdentifier(_options.IssuerName);

            var nameId = new Saml2NameIdentifier(outgoingNameId.Value);

            var subjectConfirmationData = new Saml2SubjectConfirmationData();

            subjectConfirmationData.NotOnOrAfter = now.AddMinutes(
                rp.TokenLifetimeInMinutes.GetValueOrDefault(_options.DefaultNotOnOrAfterInMinutes));

            if (request.Parameters.ContainsKey("Recipient"))
            {
                subjectConfirmationData.Recipient = new Uri(request.Parameters["Recipient"]);
            }
            else
            {
                subjectConfirmationData.Recipient = new Uri(rp.ReplyUrl);
            }

            var subjectConfirmation = new Saml2SubjectConfirmation(new Uri("urn:oasis:names:tc:SAML:2.0:cm:bearer"),
                                                                   subjectConfirmationData);

            subjectConfirmation.NameIdentifier = nameId;

            var subject = new Saml2Subject(subjectConfirmation);

            var conditions = new Saml2Conditions(new Saml2AudienceRestriction[]
            {
                new Saml2AudienceRestriction(request.Realm)
            });

            conditions.NotOnOrAfter = now.AddMinutes(
                rp.TokenLifetimeInMinutes.GetValueOrDefault(_options.DefaultNotOnOrAfterInMinutes));
            conditions.NotBefore = now.Subtract(TimeSpan.FromMinutes(_options.DefaultNotBeforeInMinutes));

            var authContext = new Saml2AuthenticationContext(new Uri("urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"));

            var authStatement = new Saml2AuthenticationStatement(authContext, now);

            authStatement.SessionIndex = (request.Parameters.ContainsKey("SessionIndex")) ? request.Parameters["SessionIndex"] : null;

            var attributeStament = new Saml2AttributeStatement();

            foreach (var claim in outgoingSubject.Claims)
            {
                _logger.LogDebug("Adding attribute in SAML token '{0} - {1}'", claim.Type, claim.Value);

                attributeStament.Attributes.Add(new Saml2Attribute(claim.Type, claim.Value));
            }

            var assertion = new Saml2Assertion(issuer);

            assertion.Id         = new Saml2Id();
            assertion.Subject    = subject;
            assertion.Conditions = conditions;
            assertion.Statements.Add(attributeStament);
            assertion.Statements.Add(authStatement);
            assertion.IssueInstant = now;

            assertion.SigningCredentials = await _keyService.GetSigningCredentialsAsync();

            var token = new Saml2SecurityToken(assertion);

            token.SigningKey = assertion.SigningCredentials.Key;

            return(token);
        }
コード例 #26
0
 public Saml2EncryptedAssertion(Saml2NameIdentifier issuer) :
     base(issuer)
 {
 }