Skip to content

[dotnet-svcutil] Update CustomBinding TransportSecurityBindingElement… #5789

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 111 additions & 8 deletions src/dotnet-svcutil/lib/src/CodeDomFixup/MethodCreationHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.

using System;
using Microsoft.CodeDom;
using System.Collections.Generic;
using System.Globalization;
using System.Net;
Expand All @@ -12,6 +11,7 @@
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.Text;
using Microsoft.CodeDom;
using Microsoft.Xml;

namespace Microsoft.Tools.ServiceModel.Svcutil
Expand Down Expand Up @@ -1115,16 +1115,106 @@ private static void AddWinStreamSecurityBindingElement(CodeStatementCollection s

private static void AddTransportSecurityBindingElement(CodeStatementCollection statements, CodeVariableReferenceExpression customBinding, TransportSecurityBindingElement bindingElement)
{
// Security binding validation is done in EndpointSelector.cs - Add UserNameOverTransportBindingElement
TransportSecurityBindingElement defaultBindingElement = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
CodeVariableDeclarationStatement userNameOverTransportSecurityBindingElement = new CodeVariableDeclarationStatement(
TransportSecurityBindingElement defaultBindingElement;
string defaultBindingElementFactoryMethodName;
CodeExpression[] defaultBindingElementFactoryMethodExpressionParameters = Array.Empty<CodeExpression>();

// CertificateOverTransport
if (SecurityBindingElement.IsCertificateOverTransportBinding(bindingElement))
{
defaultBindingElement = SecurityBindingElement.CreateCertificateOverTransportBindingElement();
defaultBindingElementFactoryMethodName = nameof(SecurityBindingElement.CreateCertificateOverTransportBindingElement);
}

// IssuedTokenOverTransport
else if (SecurityBindingElement.IsIssuedTokenOverTransportBinding(bindingElement,
out System.ServiceModel.Security.Tokens.IssuedSecurityTokenParameters issuedTokenOverTransportParameters))
{
defaultBindingElement = SecurityBindingElement.CreateIssuedTokenOverTransportBindingElement(issuedTokenOverTransportParameters);
defaultBindingElementFactoryMethodName = nameof(SecurityBindingElement.CreateIssuedTokenOverTransportBindingElement);

statements.Add(new CodeVariableDeclarationStatement(
issuedTokenOverTransportParameters.IssuerBinding.GetType(),
"issuerBinding",
new CodeObjectCreateExpression(issuedTokenOverTransportParameters.IssuerBinding.GetType())));

statements.Add(new CodeVariableDeclarationStatement(
typeof(EndpointAddress),
"issuerAddress",
new CodeObjectCreateExpression(typeof(EndpointAddress),
new CodeObjectCreateExpression(typeof(Uri),
new CodePrimitiveExpression(issuedTokenOverTransportParameters.IssuerAddress.ToString())))));

statements.Add(new CodeVariableDeclarationStatement(
typeof(System.ServiceModel.Security.Tokens.IssuedSecurityTokenParameters),
"issuedTokenParameters",
new CodeObjectCreateExpression(
typeof(System.ServiceModel.Security.Tokens.IssuedSecurityTokenParameters),
new CodeExpression[]
{
new CodePrimitiveExpression(issuedTokenOverTransportParameters.TokenType),
new CodeVariableReferenceExpression("issuerAddress"),
new CodeVariableReferenceExpression("issuerBinding")
})));

statements.Add(new CodeAssignStatement(
new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("issuedTokenParameters"), "KeySize"),
new CodePrimitiveExpression(issuedTokenOverTransportParameters.KeySize)));

statements.Add(new CodeAssignStatement(
new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("issuedTokenParameters"), "UseStrTransform"),
new CodePrimitiveExpression(issuedTokenOverTransportParameters.UseStrTransform)));


defaultBindingElementFactoryMethodExpressionParameters = new CodeExpression[]
{
new CodeVariableReferenceExpression("issuedTokenParameters")
};
}

// KerberosOverTransport
else if (SecurityBindingElement.IsKerberosBinding(bindingElement))
{
defaultBindingElement = SecurityBindingElement.CreateKerberosOverTransportBindingElement();
defaultBindingElementFactoryMethodName = nameof(SecurityBindingElement.CreateKerberosOverTransportBindingElement);
}

// SspiNegotiatedOverTransport
else if (SecurityBindingElement.IsSspiNegotiationOverTransportBinding(bindingElement, requireCancellation: true))
{
defaultBindingElement = SecurityBindingElement.CreateSspiNegotiationOverTransportBindingElement();
defaultBindingElementFactoryMethodName = nameof(SecurityBindingElement.CreateSspiNegotiationOverTransportBindingElement);
}
else if (SecurityBindingElement.IsSspiNegotiationOverTransportBinding(bindingElement, requireCancellation: false))
{
defaultBindingElement = SecurityBindingElement.CreateSspiNegotiationOverTransportBindingElement(false);
defaultBindingElementFactoryMethodName = nameof(SecurityBindingElement.CreateSspiNegotiationOverTransportBindingElement);
defaultBindingElementFactoryMethodExpressionParameters = new CodeExpression[]
{
new CodePrimitiveExpression(false)
};
}

// UserNameOverTransport
else if (SecurityBindingElement.IsUserNameOverTransportBinding(bindingElement))
{
defaultBindingElement = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
defaultBindingElementFactoryMethodName = nameof(SecurityBindingElement.CreateUserNameOverTransportBindingElement);
}
else
{
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, SR.ErrBindingElementNotSupportedFormat, bindingElement.GetType()));
}

CodeVariableDeclarationStatement transportSecurityBindingElement = new CodeVariableDeclarationStatement(
typeof(TransportSecurityBindingElement),
"userNameOverTransportSecurityBindingElement",
"transportSecurityBindingElement",
new CodeMethodInvokeExpression(
new CodeTypeReferenceExpression(typeof(SecurityBindingElement)),
"CreateUserNameOverTransportBindingElement"));
statements.Add(userNameOverTransportSecurityBindingElement);
CodeVariableReferenceExpression bindingElementRef = new CodeVariableReferenceExpression(userNameOverTransportSecurityBindingElement.Name);
defaultBindingElementFactoryMethodName,
defaultBindingElementFactoryMethodExpressionParameters));
statements.Add(transportSecurityBindingElement);
CodeVariableReferenceExpression bindingElementRef = new CodeVariableReferenceExpression(transportSecurityBindingElement.Name);

if (defaultBindingElement.IncludeTimestamp != bindingElement.IncludeTimestamp)
{
Expand Down Expand Up @@ -1386,6 +1476,19 @@ private static void AddHttpBindingElement(CodeStatementCollection statements, Co
"MaxReceivedMessageSize"),
new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(typeof(int)), "MaxValue")));

if (isHttps)
{
var defaultHttpsBindingElement = defaultBindingElement as HttpsTransportBindingElement;
var httpsBindingElement = bindingElement as HttpsTransportBindingElement;
if (defaultHttpsBindingElement.RequireClientCertificate != httpsBindingElement.RequireClientCertificate)
{
statements.Add(
new CodeAssignStatement(
new CodePropertyReferenceExpression(bindingElementRef, "RequireClientCertificate"),
new CodePrimitiveExpression(httpsBindingElement.RequireClientCertificate)));
}
}

if (defaultBindingElement.TransferMode != bindingElement.TransferMode)
{
statements.Add(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace CertificateAuth_NS
{


[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "99.99.99")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="CertificateAuth_NS.IService")]
public interface IService
{

[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService/GetMessage", ReplyAction="http://tempuri.org/IService/GetMessageResponse")]
System.Threading.Tasks.Task<string> GetMessageAsync();
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "99.99.99")]
public interface IServiceChannel : CertificateAuth_NS.IService, System.ServiceModel.IClientChannel
{
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "99.99.99")]
public partial class ServiceClient : System.ServiceModel.ClientBase<CertificateAuth_NS.IService>, CertificateAuth_NS.IService
{

/// <summary>
/// Implement this partial method to configure the service endpoint.
/// </summary>
/// <param name="serviceEndpoint">The endpoint to configure</param>
/// <param name="clientCredentials">The client credentials</param>
static partial void ConfigureEndpoint(System.ServiceModel.Description.ServiceEndpoint serviceEndpoint, System.ServiceModel.Description.ClientCredentials clientCredentials);

public ServiceClient(EndpointConfiguration endpointConfiguration) :
base(ServiceClient.GetBindingForEndpoint(endpointConfiguration), ServiceClient.GetEndpointAddress(endpointConfiguration))
{
this.Endpoint.Name = endpointConfiguration.ToString();
ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
}

public ServiceClient(EndpointConfiguration endpointConfiguration, string remoteAddress) :
base(ServiceClient.GetBindingForEndpoint(endpointConfiguration), new System.ServiceModel.EndpointAddress(remoteAddress))
{
this.Endpoint.Name = endpointConfiguration.ToString();
ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
}

public ServiceClient(EndpointConfiguration endpointConfiguration, System.ServiceModel.EndpointAddress remoteAddress) :
base(ServiceClient.GetBindingForEndpoint(endpointConfiguration), remoteAddress)
{
this.Endpoint.Name = endpointConfiguration.ToString();
ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
}

public ServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress)
{
}

public System.Threading.Tasks.Task<string> GetMessageAsync()
{
return base.Channel.GetMessageAsync();
}

public virtual System.Threading.Tasks.Task OpenAsync()
{
return System.Threading.Tasks.Task.Factory.FromAsync(((System.ServiceModel.ICommunicationObject)(this)).BeginOpen(null, null), new System.Action<System.IAsyncResult>(((System.ServiceModel.ICommunicationObject)(this)).EndOpen));
}

#if !NET6_0_OR_GREATER
public virtual System.Threading.Tasks.Task CloseAsync()
{
return System.Threading.Tasks.Task.Factory.FromAsync(((System.ServiceModel.ICommunicationObject)(this)).BeginClose(null, null), new System.Action<System.IAsyncResult>(((System.ServiceModel.ICommunicationObject)(this)).EndClose));
}
#endif

private static System.ServiceModel.Channels.Binding GetBindingForEndpoint(EndpointConfiguration endpointConfiguration)
{
if ((endpointConfiguration == EndpointConfiguration.WSHttpBinding_IService))
{
System.ServiceModel.WSHttpBinding result = new System.ServiceModel.WSHttpBinding();
result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
result.MaxReceivedMessageSize = int.MaxValue;
result.AllowCookies = true;
result.Security.Mode = System.ServiceModel.SecurityMode.Transport;
result.Security.Transport.ClientCredentialType = System.ServiceModel.HttpClientCredentialType.Certificate;
return result;
}
if ((endpointConfiguration == EndpointConfiguration.CustomBinding_IService))
{
System.ServiceModel.Channels.CustomBinding result = new System.ServiceModel.Channels.CustomBinding();
System.ServiceModel.Channels.TransportSecurityBindingElement transportSecurityBindingElement = System.ServiceModel.Channels.SecurityBindingElement.CreateCertificateOverTransportBindingElement();
transportSecurityBindingElement.MessageSecurityVersion = System.ServiceModel.MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10;
result.Elements.Add(transportSecurityBindingElement);
result.Elements.Add(new System.ServiceModel.Channels.BinaryMessageEncodingBindingElement());
System.ServiceModel.Channels.HttpsTransportBindingElement httpsBindingElement = new System.ServiceModel.Channels.HttpsTransportBindingElement();
httpsBindingElement.AllowCookies = true;
httpsBindingElement.MaxBufferSize = int.MaxValue;
httpsBindingElement.MaxReceivedMessageSize = int.MaxValue;
httpsBindingElement.RequireClientCertificate = true;
result.Elements.Add(httpsBindingElement);
return result;
}
throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration));
}

private static System.ServiceModel.EndpointAddress GetEndpointAddress(EndpointConfiguration endpointConfiguration)
{
if ((endpointConfiguration == EndpointConfiguration.WSHttpBinding_IService))
{
return new System.ServiceModel.EndpointAddress(new System.Uri("https://contoso.com:8123/Service"), new System.ServiceModel.DnsEndpointIdentity("Contoso.com"));
}
if ((endpointConfiguration == EndpointConfiguration.CustomBinding_IService))
{
return new System.ServiceModel.EndpointAddress(new System.Uri("https://contoso.com:8123/Service/custom"), new System.ServiceModel.DnsEndpointIdentity("Contoso.com"));
}
throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration));
}

public enum EndpointConfiguration
{

WSHttpBinding_IService,

CustomBinding_IService,
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"providerId": "Microsoft.Tools.ServiceModel.Svcutil",
"version": "99.99.99",
"options": {
"inputs": [
"../../../../../src/dotnet-svcutil/lib/tests/TestCases/wsdl/CertificateAuth.wsdl"
],
"namespaceMappings": [
"*, CertificateAuth_NS"
],
"outputFile": "Reference.cs",
"targetFramework": "N.N",
"typeReuseMode": "None"
}
}
Loading
Loading