public void SerializeRequestedSecurityToken()
        {
            var rstr       = RequestSecurityTokenResponseSerializer.Deserialize(WResult_Saml2_Valid);
            var rstrString = RequestSecurityTokenResponseSerializer.Serialize(rstr);

            StringAssert.Contains(rstrString, "RequestedSecurityToken");
            StringAssert.Contains(rstrString, "Assertion");
        }
Exemplo n.º 2
0
        public async Task <string> GenerateSerializedRstr(ValidatedWsFederationSigninRequest request)
        {
            var now = _clock.UtcNow.UtcDateTime;

            var principal   = request.Subject.Identity as ClaimsIdentity;
            var nameIdClaim = principal.FindFirst(ClaimTypes.NameIdentifier);

            if (nameIdClaim == null)
            {
                nameIdClaim = new Claim(ClaimTypes.NameIdentifier, principal.Name);
                nameIdClaim.Properties.Add(ClaimProperties.SamlNameIdentifierFormat, Saml2Constants.NameIdentifierFormats.UnspecifiedString);
                principal.AddClaim(nameIdClaim);
            }

            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Audience           = request.RequestMessage.Wtrealm,
                Expires            = now.AddSeconds(request.Client.IdentityTokenLifetime),
                IssuedAt           = now,
                Issuer             = _options.IssuerUri,
                NotBefore          = now,
                SigningCredentials = await _keys.GetSigningCredentialsAsync(),
                Subject            = principal
            };

            //For whatever reason, the Digest method isn't specified in the builder extensions for identity server.
            //Not a good solution to force the user to use th eoverload that takes SigningCredentials
            //IdentityServer4/Configuration/DependencyInjection/BuilderExtensions/Crypto.cs
            //Instead, it should be supported in:
            //  The overload that takes a X509Certificate2
            //  The overload that looks it up in a cert store
            //  The overload that takes an RsaSecurityKey
            //  AddDeveloperSigningCredential
            //For now, this is a workaround.
            if (tokenDescriptor.SigningCredentials.Digest == null)
            {
                _logger.LogInformation($"SigningCredentials does not have a digest specified. Using default digest algorithm of {SecurityAlgorithms.Sha256Digest}");
                tokenDescriptor.SigningCredentials = new SigningCredentials(tokenDescriptor.SigningCredentials.Key, tokenDescriptor.SigningCredentials.Algorithm, SecurityAlgorithms.Sha256Digest);
            }

            _logger.LogDebug("Creating SAML 2.0 security token.");
            var tokenHandler = new Saml2SecurityTokenHandler();
            var token        = tokenHandler.CreateToken(tokenDescriptor);

            _logger.LogDebug("Serializing RSTR.");
            var rstr = new RequestSecurityTokenResponse
            {
                AppliesTo = new AppliesTo(request.RequestMessage.Wtrealm),
                KeyType   = "http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey",
                Lifetime  = new Lifetime(now, now.AddSeconds(request.Client.IdentityTokenLifetime)),
                RequestedSecurityToken = token,
                RequestType            = "http://schemas.xmlsoap.org/ws/2005/02/trust/Issue",
                TokenType = "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0"
            };

            return(RequestSecurityTokenResponseSerializer.Serialize(rstr));
        }
Exemplo n.º 3
0
        public async Task <string> GenerateSerializedRstr(ValidatedWsFederationRequest request)
        {
            var now        = _clock.UtcNow.UtcDateTime;
            var credential = await _keys.GetSigningCredentialsAsync();

            var key = credential.Key as X509SecurityKey;

            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Audience           = request.RequestMessage.Wtrealm,
                Expires            = now.AddSeconds(request.Client.IdentityTokenLifetime),
                IssuedAt           = now,
                Issuer             = _options.IssuerUri,
                NotBefore          = now,
                SigningCredentials = key == null ? credential : new X509SigningCredentials(key.Certificate, _federationOptions.DefaultSignatureAlgorithm),
                Subject            = await CreateSubjectAsync(request)
            };

            //For whatever reason, the Digest method isn't specified in the builder extensions for identity server.
            //Not a good solution to force the user to use the overload that takes SigningCredentials
            //IdentityServer4/Configuration/DependencyInjection/BuilderExtensions/Crypto.cs
            //Instead, it should be supported in:
            //  The overload that takes a X509Certificate2
            //  The overload that looks it up in a cert store
            //  The overload that takes an RsaSecurityKey
            //  AddDeveloperSigningCredential
            //For now, this is a workaround.
            if (tokenDescriptor.SigningCredentials.Digest == null)
            {
                _logger.LogInformation($"SigningCredentials does not have a digest specified. Using default digest algorithm of {SecurityAlgorithms.Sha256Digest}");
                tokenDescriptor.SigningCredentials = new SigningCredentials(tokenDescriptor.SigningCredentials.Key, tokenDescriptor.SigningCredentials.Algorithm ?? _federationOptions.DefaultSignatureAlgorithm, _federationOptions.DefaultDigestAlgorithm);
            }

            _logger.LogDebug("Creating SAML 2.0 security token.");

            var tokenHandler = new Saml2SecurityTokenHandler();
            var token        = tokenHandler.CreateToken(tokenDescriptor);

            _logger.LogDebug("Serializing RSTR.");
            var rstr = new RequestSecurityTokenResponse
            {
                AppliesTo = new AppliesTo(request.RequestMessage.Wtrealm),
                KeyType   = "http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey",
                Lifetime  = new Lifetime
                {
                    Created = XmlConvert.ToString(now, XmlDateTimeSerializationMode.Utc),
                    Expires = XmlConvert.ToString(now.AddSeconds(request.Client.IdentityTokenLifetime), XmlDateTimeSerializationMode.Utc),
                },
                RequestedSecurityToken = token,
                RequestType            = "http://schemas.xmlsoap.org/ws/2005/02/trust/Issue",
                TokenType = WsFederationConstants.TokenTypes.Saml2TokenProfile11
            };

            return(RequestSecurityTokenResponseSerializer.Serialize(rstr));
        }
        public void SerializeBaseRstrAttributes()
        {
            var rstr       = RequestSecurityTokenResponseSerializer.Deserialize(WResult_Saml2_Valid);
            var rstrString = RequestSecurityTokenResponseSerializer.Serialize(rstr);

            StringAssert.Contains(rstrString, "RequestSecurityTokenResponse");
            StringAssert.Contains(rstrString, "Lifetime");
            StringAssert.Contains(rstrString, "AppliesTo");
            StringAssert.Contains(rstrString, "TokenType");
            StringAssert.Contains(rstrString, "RequestType");
            StringAssert.Contains(rstrString, "KeyType");
        }
        public void DeserializeSaml2Token()
        {
            var rstr = RequestSecurityTokenResponseSerializer.Deserialize(WResult_Saml2_Valid);

            Assert.IsNotNull(rstr);

            Assert.IsNotNull(rstr.RequestedSecurityToken);
            Assert.AreEqual("https://sts.windows.net/add29489-7269-41f4-8841-b63c95564420/", rstr.RequestedSecurityToken.Issuer);

            var samlToken = rstr.RequestedSecurityToken as Saml2SecurityToken;

            Assert.IsNotNull(samlToken);
            Assert.AreEqual("_edc15efd-1117-4bf9-89da-28b1663fb890", samlToken.Assertion.Id.Value);
            Assert.AreEqual("https://sts.windows.net/add29489-7269-41f4-8841-b63c95564420/", samlToken.Assertion.Issuer.Value);
        }
        public void DeserializeBaseRstrAttributes()
        {
            var rstr = RequestSecurityTokenResponseSerializer.Deserialize(WResult_Saml2_Valid);

            Assert.IsNotNull(rstr);

            Assert.IsNotNull(rstr.Lifetime);
            Assert.AreEqual(DateTime.Parse("2017-04-23T16:11:17.348Z").ToUniversalTime(), rstr.Lifetime.Created.Value);
            Assert.AreEqual(DateTime.Parse("2017-04-23T17:11:17.348Z").ToUniversalTime(), rstr.Lifetime.Expires.Value);

            Assert.IsNotNull(rstr.AppliesTo);
            Assert.IsNotNull(rstr.AppliesTo.EndpointReference);
            Assert.IsNotNull(rstr.AppliesTo.EndpointReference.Address);
            Assert.AreEqual("spn:fe78e0b4-6fe7-47e6-812c-fb75cee266a4", rstr.AppliesTo.EndpointReference.Address);

            Assert.AreEqual("http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0", rstr.TokenType);
            Assert.AreEqual("http://schemas.xmlsoap.org/ws/2005/02/trust/Issue", rstr.RequestType);
            Assert.AreEqual("http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey", rstr.KeyType);
        }