Example #1
0
        public void RoundTripWsMetadata(EnvelopedSignatureTheoryData theoryData)
        {
            var context = TestUtilities.WriteHeader($"{this}.RoundTripWsMetadata", theoryData);

            try
            {
                var settings = new XmlWriterSettings
                {
                    Encoding = new UTF8Encoding(false)
                };

                var buffer = new MemoryStream();
                var esw    = new EnvelopedSignatureWriter(XmlWriter.Create(buffer, settings), theoryData.SigningCredentials, theoryData.ReferenceId);

                theoryData.Action.DynamicInvoke(esw);

                var metadata      = Encoding.UTF8.GetString(buffer.ToArray());
                var configuration = new WsFederationConfiguration();
                var reader        = XmlReader.Create(new StringReader(metadata));
                configuration = new WsFederationMetadataSerializer().ReadMetadata(reader);
                configuration.Signature.Verify(theoryData.SigningCredentials.Key, theoryData.SigningCredentials.Key.CryptoProviderFactory);
                theoryData.ExpectedException.ProcessNoException(context);
            }
            catch (Exception ex)
            {
                theoryData.ExpectedException.ProcessException(ex, context);
            }

            TestUtilities.AssertFailIfErrors(context);
        }
Example #2
0
        public MetadataMiddleware(RequestDelegate next,
                                  ILogger <MetadataMiddleware> logger,
                                  IKeyMaterialService keyService,
                                  IOptions <FederationGatewayOptions> options,
                                  WsFederationMetadataSerializer serializer)
        {
            if (next == null)
            {
                throw new ArgumentNullException(nameof(next));
            }
            if (keyService == null)
            {
                throw new ArgumentNullException(nameof(keyService));
            }
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }
            if (serializer == null)
            {
                throw new ArgumentNullException(nameof(serializer));
            }

            _next       = next;
            _logger     = logger;
            _keyService = keyService;
            _options    = options.Value;
            _serializer = serializer;
        }
Example #3
0
        public void WriteMetadata(WsFederationMetadataTheoryData theoryData)
        {
            TestUtilities.WriteHeader($"{this}.WriteMetadata", theoryData);
            var context = new CompareContext($"{this}.WriteMetadata, {theoryData.TestId}");

            try
            {
                var settings = new XmlWriterSettings();
                var builder  = new StringBuilder();

                if (theoryData.UseNullWriter)
                {
                    theoryData.Serializer.WriteMetadata(null, theoryData.Configuration);
                    theoryData.ExpectedException.ProcessNoException(context);
                }
                else
                {
                    using (var writer = XmlWriter.Create(builder, settings))
                    {
                        // add signingCredentials so we can created signed metadata.
                        if (theoryData.Configuration != null)
                        {
                            theoryData.Configuration.SigningCredentials = KeyingMaterial.DefaultX509SigningCreds_2048_RsaSha2_Sha2;
                        }

                        // write configuration content into metadata and sign the metadata
                        var serializer = new WsFederationMetadataSerializer();
                        serializer.WriteMetadata(writer, theoryData.Configuration);
                        writer.Flush();
                        var metadata = builder.ToString();

                        // read the created metadata into a new configuration
                        var reader        = XmlReader.Create(new StringReader(metadata));
                        var configuration = theoryData.Serializer.ReadMetadata(reader);

                        // assign signingcredentials and verify the signature of created metadata
                        configuration.SigningCredentials = theoryData.Configuration.SigningCredentials;
                        if (configuration.SigningCredentials != null)
                        {
                            configuration.Signature.Verify(configuration.SigningCredentials.Key, configuration.SigningCredentials.Key.CryptoProviderFactory);
                        }

                        // remove the signature and do the comparison
                        configuration.Signature = null;
                        theoryData.ExpectedException.ProcessNoException(context);
                        IdentityComparer.AreWsFederationConfigurationsEqual(configuration, theoryData.Configuration, context);
                    }
                }
            }
            catch (Exception ex)
            {
                theoryData.ExpectedException.ProcessException(ex, context);
            }

            TestUtilities.AssertFailIfErrors(context);
        }
    /// <summary>
    ///
    /// </summary>
    /// <param name="writer"></param>
    /// <param name="configuration"></param>
    /// <returns></returns>
    public static void WriteMetadata(this WsFederationMetadataSerializer serializer, XmlWriter writer, WsFederationConfiguration configuration)
    {
        if (writer == null)
        {
            throw new ArgumentNullException(nameof(writer));
        }

        if (configuration == null)
        {
            throw new ArgumentNullException(nameof(configuration));
        }

        if (string.IsNullOrEmpty(configuration.Issuer))
        {
            throw XmlUtil.LogWriteException(nameof(configuration.Issuer) + " is null or empty");
        }

        if (string.IsNullOrEmpty(configuration.TokenEndpoint))
        {
            throw XmlUtil.LogWriteException(nameof(configuration.TokenEndpoint) + " is null or empty");
        }

        X509SecurityKey          securityKey        = configuration.SigningKeys.FirstOrDefault() as X509SecurityKey;
        var                      entityDescriptorId = "_" + Guid.NewGuid().ToString();
        EnvelopedSignatureWriter envelopeWriter     = null;

        if (securityKey != null)
        {
            envelopeWriter = new EnvelopedSignatureWriter(
                writer,
                configuration.SigningCredentials,
                "#" + entityDescriptorId);
            writer = envelopeWriter;
        }

        writer.WriteStartDocument();

        // <EntityDescriptor>
        writer.WriteStartElement(Elements.EntityDescriptor, WsFederationConstants.MetadataNamespace);
        // @entityID
        writer.WriteAttributeString(Attributes.EntityId, configuration.Issuer);
        // @ID
        writer.WriteAttributeString(Attributes.Id, entityDescriptorId);

        // if (envelopeWriter != null)
        //     envelopeWriter.WriteSignature();

        WriteSecurityTokenServiceTypeRoleDescriptor(configuration, writer);

        // </EntityDescriptor>
        writer.WriteEndElement();

        writer.WriteEndDocument();
    }
        public async Task Metadata_CanBeDeserializedAsMetadata()
        {
            var response = await _client.GetAsync("/wsfederation/metadata");

            var content = await response.Content.ReadAsStreamAsync();

            using (var reader = XmlReader.Create(content))
            {
                var serializer    = new WsFederationMetadataSerializer();
                var configuration = serializer.ReadMetadata(reader);
                Assert.AreEqual("http://localhost/wsfederation", configuration.TokenEndpoint);
            }
        }
Example #6
0
        /// <summary>
        /// Executes the result operation of the action method asynchronously. This method is called by MVC to process
        /// the result of an action method.
        /// </summary>
        /// <param name="context">The context in which the result is executed. The context information includes
        /// information about the action that was executed and request information.</param>
        /// <returns>
        /// A task that represents the asynchronous execute operation.
        /// </returns>
        public Task ExecuteResultAsync(ActionContext context)
        {
            var ser = new WsFederationMetadataSerializer();

            using var ms           = new MemoryStream();
            using XmlWriter writer = XmlDictionaryWriter.CreateTextWriter(ms, Encoding.UTF8, false);
            ser.WriteMetadata(writer, _config);
            writer.Flush();
            context.HttpContext.Response.ContentType = "application/xml";
            var metaAsString = Encoding.UTF8.GetString(ms.ToArray());

            return(context.HttpContext.Response.WriteAsync(metaAsString));
        }
Example #7
0
        public async Task Metadata_should_return_metadata_document_with_key_rotation()
        {
            var configuration = new Dictionary <string, string>
            {
                ["IdentityServer:Key:Type"] = "KeysRotation",
                ["Seed"] = "false"
            };
            var sut = TestUtils.CreateTestServer(configurationOverrides: configuration);

            using var client   = sut.CreateClient();
            using var response = await client.GetAsync("/wsfederation/metadata");

            Assert.Equal(HttpStatusCode.OK, response.StatusCode);

            using var reader = XmlReader.Create(await response.Content.ReadAsStreamAsync().ConfigureAwait(false));
            var serializer = new WsFederationMetadataSerializer();
            var metadata   = serializer.ReadMetadata(reader);

            Assert.NotNull(metadata);
        }
Example #8
0
        public async Task <string> GetMetadata(HttpContext context)
        {
            var configuration = new WsFederationConfiguration
            {
                Issuer             = _options.IssuerUri,
                SigningCredentials = await _keys.GetSigningCredentialsAsync(),
                TokenEndpoint      = context.GetIdentityServerOrigin() + "/wsfederation"
            };

            //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 (configuration.SigningCredentials.Digest == null)
            {
                _logger.LogInformation($"SigningCredentials does not have a digest specified. Using default digest algorithm of {SecurityAlgorithms.Sha256Digest}");
                configuration.SigningCredentials = new SigningCredentials(configuration.SigningCredentials.Key, configuration.SigningCredentials.Algorithm ?? SecurityAlgorithms.RsaSha256Signature, SecurityAlgorithms.Sha256Digest);
            }
            configuration.KeyInfos.Add(new KeyInfo(configuration.SigningCredentials.Key));

            var serializer = new WsFederationMetadataSerializer();

            var sb       = new StringBuilder();
            var settings = new XmlWriterSettings
            {
                OmitXmlDeclaration = true
            };

            using (var writer = XmlWriter.Create(sb, settings))
            {
                serializer.WriteMetadata(writer, configuration);
            }
            var metadata = sb.ToString();

            return(metadata);
        }
Example #9
0
        public static IssuerSigningKeys GetSigningKeys(string metadataEndpoint, TimeSpan backchannelTimeout, HttpMessageHandler backchannelHttpHandler)
        {
            using (var metadataRequest = new HttpClient(backchannelHttpHandler, false))
            {
                metadataRequest.Timeout = backchannelTimeout;
                using (HttpResponseMessage metadataResponse = metadataRequest.GetAsync(metadataEndpoint).Result)
                {
                    metadataResponse.EnsureSuccessStatusCode();
                    Stream metadataStream = metadataResponse.Content.ReadAsStreamAsync().Result;
                    using (XmlReader metaDataReader = XmlReader.Create(metadataStream, SafeSettings))
                    {
                        var serializer = new WsFederationMetadataSerializer();
                        var wsFederationConfiguration = serializer.ReadMetadata(metaDataReader);

                        return(new IssuerSigningKeys {
                            Issuer = wsFederationConfiguration.Issuer, Keys = wsFederationConfiguration.SigningKeys
                        });
                    }
                }
            }
        }