|
3 | 3 | // See the LICENSE file in the project root for more information.
|
4 | 4 |
|
5 | 5 | using System;
|
6 |
| -using Microsoft.CodeDom; |
7 | 6 | using System.Collections.Generic;
|
8 | 7 | using System.Globalization;
|
9 | 8 | using System.Net;
|
|
12 | 11 | using System.ServiceModel.Channels;
|
13 | 12 | using System.ServiceModel.Description;
|
14 | 13 | using System.Text;
|
| 14 | +using Microsoft.CodeDom; |
15 | 15 | using Microsoft.Xml;
|
16 | 16 |
|
17 | 17 | namespace Microsoft.Tools.ServiceModel.Svcutil
|
@@ -1115,16 +1115,98 @@ private static void AddWinStreamSecurityBindingElement(CodeStatementCollection s
|
1115 | 1115 |
|
1116 | 1116 | private static void AddTransportSecurityBindingElement(CodeStatementCollection statements, CodeVariableReferenceExpression customBinding, TransportSecurityBindingElement bindingElement)
|
1117 | 1117 | {
|
1118 |
| - // Security binding validation is done in EndpointSelector.cs - Add UserNameOverTransportBindingElement |
1119 |
| - TransportSecurityBindingElement defaultBindingElement = SecurityBindingElement.CreateUserNameOverTransportBindingElement(); |
1120 |
| - CodeVariableDeclarationStatement userNameOverTransportSecurityBindingElement = new CodeVariableDeclarationStatement( |
| 1118 | + TransportSecurityBindingElement defaultBindingElement; |
| 1119 | + string defaultBindingElementFactoryMethodName; |
| 1120 | + CodeExpression[] defaultBindingElementFactoryMethodExpressionParameters = Array.Empty<CodeExpression>(); |
| 1121 | + |
| 1122 | + // CertificateOverTransport |
| 1123 | + // [carol] Validated: correctly generates code |
| 1124 | + if (SecurityBindingElement.IsCertificateOverTransportBinding(bindingElement)) |
| 1125 | + { |
| 1126 | + defaultBindingElement = SecurityBindingElement.CreateCertificateOverTransportBindingElement(); |
| 1127 | + defaultBindingElementFactoryMethodName = nameof(SecurityBindingElement.CreateCertificateOverTransportBindingElement); |
| 1128 | + } |
| 1129 | + // IssuedTokenOverTransport |
| 1130 | + else if (SecurityBindingElement.IsIssuedTokenOverTransportBinding(bindingElement, |
| 1131 | + out System.ServiceModel.Security.Tokens.IssuedSecurityTokenParameters issuedTokenOverTransportParameters)) |
| 1132 | + { |
| 1133 | + defaultBindingElement = SecurityBindingElement.CreateIssuedTokenOverTransportBindingElement(issuedTokenOverTransportParameters); |
| 1134 | + defaultBindingElementFactoryMethodName = nameof(SecurityBindingElement.CreateIssuedTokenOverTransportBindingElement); |
| 1135 | + |
| 1136 | + statements.Add(new CodeVariableDeclarationStatement( |
| 1137 | + issuedTokenOverTransportParameters.IssuerBinding.GetType(), |
| 1138 | + "issuerBinding", |
| 1139 | + new CodeObjectCreateExpression(issuedTokenOverTransportParameters.IssuerBinding.GetType()))); |
| 1140 | + |
| 1141 | + statements.Add(new CodeVariableDeclarationStatement( |
| 1142 | + typeof(EndpointAddress), |
| 1143 | + "issuerAddress", |
| 1144 | + new CodeObjectCreateExpression(typeof(EndpointAddress), |
| 1145 | + new CodeObjectCreateExpression(typeof(Uri), |
| 1146 | + new CodePrimitiveExpression(issuedTokenOverTransportParameters.IssuerAddress.Uri.ToString()))))); |
| 1147 | + |
| 1148 | + defaultBindingElementFactoryMethodExpressionParameters = new CodeExpression[] |
| 1149 | + { |
| 1150 | + // [carol] Updated this TODO item - need review to confirm |
| 1151 | + // TODO: pass `issuedTokenOverTransportParameters` parameter |
| 1152 | + new CodeObjectCreateExpression( |
| 1153 | + typeof(System.ServiceModel.Security.Tokens.IssuedSecurityTokenParameters), |
| 1154 | + new CodeExpression[] |
| 1155 | + { |
| 1156 | + new CodePrimitiveExpression(issuedTokenOverTransportParameters.TokenType), |
| 1157 | + new CodeVariableReferenceExpression("issuerAddress"), |
| 1158 | + new CodeVariableReferenceExpression("issuerBinding") |
| 1159 | + }) |
| 1160 | + }; |
| 1161 | + } |
| 1162 | + |
| 1163 | + // KerberosOverTransport |
| 1164 | + else if (SecurityBindingElement.IsKerberosBinding(bindingElement)) |
| 1165 | + { |
| 1166 | + defaultBindingElement = SecurityBindingElement.CreateKerberosOverTransportBindingElement(); |
| 1167 | + defaultBindingElementFactoryMethodName = nameof(SecurityBindingElement.CreateKerberosOverTransportBindingElement); |
| 1168 | + } |
| 1169 | + // SspiNegotiatedOverTransport |
| 1170 | + // [carol] Updated implementation: Whether the requireCancellation parameter is needed depends on the outcome of the method call in the following if-statements. |
| 1171 | + // TODO: make `requireCancellation` out parameter ?? |
| 1172 | + else if (SecurityBindingElement.IsSspiNegotiationOverTransportBinding(bindingElement, requireCancellation: true)) |
| 1173 | + { |
| 1174 | + defaultBindingElement = SecurityBindingElement.CreateSspiNegotiationOverTransportBindingElement(); |
| 1175 | + defaultBindingElementFactoryMethodName = nameof(SecurityBindingElement.CreateSspiNegotiationOverTransportBindingElement); |
| 1176 | + } |
| 1177 | + else if (SecurityBindingElement.IsSspiNegotiationOverTransportBinding(bindingElement, requireCancellation: false)) |
| 1178 | + { |
| 1179 | + defaultBindingElement = SecurityBindingElement.CreateSspiNegotiationOverTransportBindingElement(false); |
| 1180 | + defaultBindingElementFactoryMethodName = nameof(SecurityBindingElement.CreateSspiNegotiationOverTransportBindingElement); |
| 1181 | + defaultBindingElementFactoryMethodExpressionParameters = new CodeExpression[] |
| 1182 | + { |
| 1183 | + // [carol] Updated: The requireCancellation parameter is only necessary when setting it to false. In the parameterless constructor, requireCancellation defaults to true. |
| 1184 | + // TODO: add requireCancellation parameter |
| 1185 | + new CodePrimitiveExpression(false) |
| 1186 | + }; |
| 1187 | + } |
| 1188 | + |
| 1189 | + // UserNameOverTransport |
| 1190 | + else if (SecurityBindingElement.IsUserNameOverTransportBinding(bindingElement)) |
| 1191 | + { |
| 1192 | + defaultBindingElement = SecurityBindingElement.CreateUserNameOverTransportBindingElement(); |
| 1193 | + defaultBindingElementFactoryMethodName = nameof(SecurityBindingElement.CreateUserNameOverTransportBindingElement); |
| 1194 | + } |
| 1195 | + else |
| 1196 | + { |
| 1197 | + // TODO: throw or fallback to `CreateUserNameOverTransportBindingElement` ?? |
| 1198 | + throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, SR.ErrBindingElementNotSupportedFormat, bindingElement.GetType())); |
| 1199 | + } |
| 1200 | + |
| 1201 | + CodeVariableDeclarationStatement transportSecurityBindingElement = new CodeVariableDeclarationStatement( |
1121 | 1202 | typeof(TransportSecurityBindingElement),
|
1122 |
| - "userNameOverTransportSecurityBindingElement", |
| 1203 | + "transportSecurityBindingElement", |
1123 | 1204 | new CodeMethodInvokeExpression(
|
1124 | 1205 | new CodeTypeReferenceExpression(typeof(SecurityBindingElement)),
|
1125 |
| - "CreateUserNameOverTransportBindingElement")); |
1126 |
| - statements.Add(userNameOverTransportSecurityBindingElement); |
1127 |
| - CodeVariableReferenceExpression bindingElementRef = new CodeVariableReferenceExpression(userNameOverTransportSecurityBindingElement.Name); |
| 1206 | + defaultBindingElementFactoryMethodName, |
| 1207 | + defaultBindingElementFactoryMethodExpressionParameters)); |
| 1208 | + statements.Add(transportSecurityBindingElement); |
| 1209 | + CodeVariableReferenceExpression bindingElementRef = new CodeVariableReferenceExpression(transportSecurityBindingElement.Name); |
1128 | 1210 |
|
1129 | 1211 | if (defaultBindingElement.IncludeTimestamp != bindingElement.IncludeTimestamp)
|
1130 | 1212 | {
|
@@ -1386,6 +1468,19 @@ private static void AddHttpBindingElement(CodeStatementCollection statements, Co
|
1386 | 1468 | "MaxReceivedMessageSize"),
|
1387 | 1469 | new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(typeof(int)), "MaxValue")));
|
1388 | 1470 |
|
| 1471 | + if (isHttps) |
| 1472 | + { |
| 1473 | + var defaultHttpsBindingElement = defaultBindingElement as HttpsTransportBindingElement; |
| 1474 | + var httpsBindingElement = bindingElement as HttpsTransportBindingElement; |
| 1475 | + if (defaultHttpsBindingElement.RequireClientCertificate != httpsBindingElement.RequireClientCertificate) |
| 1476 | + { |
| 1477 | + statements.Add( |
| 1478 | + new CodeAssignStatement( |
| 1479 | + new CodePropertyReferenceExpression(bindingElementRef, "RequireClientCertificate"), |
| 1480 | + new CodePrimitiveExpression(httpsBindingElement.RequireClientCertificate))); |
| 1481 | + } |
| 1482 | + } |
| 1483 | + |
1389 | 1484 | if (defaultBindingElement.TransferMode != bindingElement.TransferMode)
|
1390 | 1485 | {
|
1391 | 1486 | statements.Add(
|
|
0 commit comments