|
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