Skip to content

Commit

Permalink
WSFed static helpers and expanded tests (dotnet#4400)
Browse files Browse the repository at this point in the history
* WSFederationHttpBinding.CreateMessgeSecurity uses Security.Message.EstablishSecurityContext to control SCT bootstrap
Remove Target and EstablishSecurityContest properties from WSTrustTokenParameters
Use DiagnosticUtility to trace exceptions
Remove M.IM.Logging direct dependency
Add comments to Federation classes
Format comments using InvariantCulture

* Fixed grammer and typos
Check for WSTrustParameters as IssuedSecurityTokenParameters in ctor of WSTrustChannelSecurityTokenProvider
Use DiagnosticUtility when throwing

* Add static helpers for WS and WS2007
Add test endpoints for WS and WS2007

Co-authored-by: brentschmaltz <brentschmaltz@hotmail.com>
Co-authored-by: Matt Connew <matt.connew@microsoft.com>
  • Loading branch information
3 people authored Oct 19, 2020
1 parent e285ec7 commit 378a5b0
Show file tree
Hide file tree
Showing 15 changed files with 412 additions and 153 deletions.
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
</PropertyGroup>

<PropertyGroup>
<MicrosoftIdentityModelProtocolsWsTrustPackageVersion>6.7.2-preview-10803222715</MicrosoftIdentityModelProtocolsWsTrustPackageVersion>
<MicrosoftIdentityModelProtocolsWsTrustPackageVersion>6.8.0</MicrosoftIdentityModelProtocolsWsTrustPackageVersion>
</PropertyGroup>

<PropertyGroup>
Expand Down
1 change: 1 addition & 0 deletions NuGet.config
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<configuration>
<packageSources>
<clear />
<add key="myget" value ="https://www.myget.org/F/azureadwebstacknightly/api/v3/index.json" />
<add key="dotnet-eng" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json" />
<add key="dotnet-tools" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -436,15 +436,15 @@ public static string WSFederationAuthorityLocalSTS
{
get
{
return GetEndpointAddress("LocalSTS.svc/transport", protocol: "https");
return GetEndpointAddress("LocalSTS.svc/", protocol: "https");
}
}

public static string Https_SecModeTransWithMessCred_ClientCredTypeIssuedTokenSaml2
{
get
{
return GetEndpointAddress("Saml2IssuedToken.svc/issued-token-using-tls", protocol: "https");
return GetEndpointAddress("Saml2IssuedToken.svc/issued-token-using-tls/", protocol: "https");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens;
using System.ServiceModel;
using System.ServiceModel.Channels;
Expand All @@ -13,14 +14,16 @@

public class WSFederationHttpBindingTests : ConditionalWcfTest
{
[WcfFact]
[Issue(2870, OS = OSID.AnyOSX)]
[Condition(nameof(Root_Certificate_Installed),
nameof(Client_Certificate_Installed),
nameof(SSL_Available))]
[OuterLoop]
public static void WSFederationHttpBindingTests_Succeeds()
[WcfTheory]
[MemberData(nameof(GetTestVariations))]
public static void WSFederationHttpBindingTests_Succeeds(MessageSecurityVersion messageSecurityVersion, SecurityKeyType securityKeyType, bool useSecureConversation, string endpointSuffix)
{
Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;
EndpointAddress issuerAddress = null;
EndpointAddress serviceEndpointAddress = null;
string tokenTargetAddress = null;
Expand All @@ -31,8 +34,8 @@ public static void WSFederationHttpBindingTests_Succeeds()
try
{
// *** SETUP *** \\
issuerAddress = new EndpointAddress(new Uri(Endpoints.WSFederationAuthorityLocalSTS));
tokenTargetAddress = Endpoints.Https_SecModeTransWithMessCred_ClientCredTypeIssuedTokenSaml2;
issuerAddress = new EndpointAddress(new Uri(Endpoints.WSFederationAuthorityLocalSTS + endpointSuffix));
tokenTargetAddress = Endpoints.Https_SecModeTransWithMessCred_ClientCredTypeIssuedTokenSaml2 + endpointSuffix + (useSecureConversation ? "/sc" : string.Empty);
serviceEndpointAddress = new EndpointAddress(new Uri(tokenTargetAddress));
var issuerBinding = new WSHttpBinding(SecurityMode.Transport);
issuerBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
Expand All @@ -42,17 +45,113 @@ public static void WSFederationHttpBindingTests_Succeeds()
{
IssuerAddress = issuerAddress,
IssuerBinding = issuerBinding,
KeyType = SecurityKeyType.BearerKey,
Target = tokenTargetAddress,
TokenType = Saml2Constants.OasisWssSaml2TokenProfile11
KeyType = securityKeyType,
TokenType = Saml2Constants.OasisWssSaml2TokenProfile11,
MessageSecurityVersion = messageSecurityVersion,
});
//federationBinding.Security.Message.EstablishSecurityContext = false;
var customBinding = new CustomBinding(federationBinding);
var sbe = customBinding.Elements.Find<SecurityBindingElement>();
sbe.MessageSecurityVersion = MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
federationBinding.Security.Message.EstablishSecurityContext = useSecureConversation;
factory = new ChannelFactory<IWcfService>(federationBinding, serviceEndpointAddress);

factory.Credentials.UserName.UserName = "AUser";
factory.Credentials.UserName.Password = "MyPassword";
serviceProxy = factory.CreateChannel();

// *** EXECUTE *** \\
string result = serviceProxy.Echo(testString);

// *** VALIDATE *** \\
Assert.Equal(testString, result);

// *** CLEANUP *** \\
((ICommunicationObject)serviceProxy).Close();
factory.Close();
}
finally
{
// *** ENSURE CLEANUP *** \\
ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
}
}

[Issue(2870, OS = OSID.AnyOSX)]
[Condition(nameof(Root_Certificate_Installed),
nameof(Client_Certificate_Installed),
nameof(SSL_Available))]
[OuterLoop]
[WcfFact]
public static void WSTrustTokeParameters_WSStaticHelper()
{
Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;
EndpointAddress issuerAddress = null;
EndpointAddress serviceEndpointAddress = null;
string tokenTargetAddress = null;
string testString = "Hello";
ChannelFactory<IWcfService> factory = null;
IWcfService serviceProxy = null;

try
{
// *** SETUP *** \\
issuerAddress = new EndpointAddress(new Uri(Endpoints.WSFederationAuthorityLocalSTS + "wsHttp/wstrustFeb2005"));
tokenTargetAddress = Endpoints.Https_SecModeTransWithMessCred_ClientCredTypeIssuedTokenSaml2 + "wsHttp/wstrustFeb2005";
serviceEndpointAddress = new EndpointAddress(new Uri(tokenTargetAddress));
var issuerBinding = new WSHttpBinding(SecurityMode.Transport);
issuerBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;

WSFederationHttpBinding federationBinding = new WSFederationHttpBinding(WSTrustTokenParameters.CreateWSFederationTokenParameters(issuerBinding, issuerAddress));
federationBinding.Security.Message.EstablishSecurityContext = false;
factory = new ChannelFactory<IWcfService>(federationBinding, serviceEndpointAddress);

factory.Credentials.UserName.UserName = "AUser";
factory.Credentials.UserName.Password = "MyPassword";
serviceProxy = factory.CreateChannel();

// *** EXECUTE *** \\
string result = serviceProxy.Echo(testString);

// *** VALIDATE *** \\
Assert.Equal(testString, result);

// *** CLEANUP *** \\
((ICommunicationObject)serviceProxy).Close();
factory.Close();
}
finally
{
// *** ENSURE CLEANUP *** \\
ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
}
}

[Issue(2870, OS = OSID.AnyOSX)]
[Condition(nameof(Root_Certificate_Installed),
nameof(Client_Certificate_Installed),
nameof(SSL_Available))]
[OuterLoop]
[WcfFact]
public static void WS2007TrustTokeParameters_WSStaticHelper()
{
Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;
EndpointAddress issuerAddress = null;
EndpointAddress serviceEndpointAddress = null;
string tokenTargetAddress = null;
string testString = "Hello";
ChannelFactory<IWcfService> factory = null;
IWcfService serviceProxy = null;

try
{
// *** SETUP *** \\
issuerAddress = new EndpointAddress(new Uri(Endpoints.WSFederationAuthorityLocalSTS + "wsHttp/wstrust13"));
tokenTargetAddress = Endpoints.Https_SecModeTransWithMessCred_ClientCredTypeIssuedTokenSaml2 + "wsHttp/wstrust13";
serviceEndpointAddress = new EndpointAddress(new Uri(tokenTargetAddress));
var issuerBinding = new WSHttpBinding(SecurityMode.Transport);
issuerBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;

WSFederationHttpBinding federationBinding = new WSFederationHttpBinding(WSTrustTokenParameters.CreateWS2007FederationTokenParameters(issuerBinding, issuerAddress));
federationBinding.Security.Message.EstablishSecurityContext = false;
factory = new ChannelFactory<IWcfService>(federationBinding, serviceEndpointAddress);

factory = new ChannelFactory<IWcfService>(customBinding, serviceEndpointAddress);
// TODO: Fix the need for this
factory.Credentials.UserName.UserName = "AUser";
factory.Credentials.UserName.Password = "MyPassword";
serviceProxy = factory.CreateChannel();
Expand All @@ -73,4 +172,14 @@ public static void WSFederationHttpBindingTests_Succeeds()
ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
}
}

public static IEnumerable<object[]> GetTestVariations()
{
// Equivalent to WS2007FederationHttpBinding
yield return new object[] { MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10, SecurityKeyType.BearerKey, false, "wsHttp/wstrust13" };
yield return new object[] { MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10, SecurityKeyType.BearerKey, true, "wsHttp/wstrust13" };
// Equivalent to WSFederationHttpBinding
yield return new object[] { MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10, SecurityKeyType.SymmetricKey, false, "wsHttp/wstrustFeb2005" };
yield return new object[] { MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10, SecurityKeyType.SymmetricKey, true, "wsHttp/wstrustFeb2005" };
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,21 @@ internal static void StartHosts()
if (success)
{
var serviceHost = (ServiceHostBase)Activator.CreateInstance(sht, serviceBaseAddresses.ToArray());
Console.WriteLine(" {0} at {1}", sht.Name, string.Join(", ", serviceBaseAddresses.Select(sba => sba.ToString())));
serviceHost.Open();
Console.Write(" {0} at ", sht.Name);
bool first = true;
foreach (var endpoint in serviceHost.Description.Endpoints)
{
if (endpoint.IsSystemEndpoint)
continue;
if(first)
first = false;
else
Console.Write(", ");

Console.Write(endpoint.Address);
}
Console.WriteLine();
}
}
catch (Exception e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.IdentityModel.Configuration;
using System.IdentityModel.Tokens;
using System.Security.Cryptography.X509Certificates;
Expand All @@ -17,18 +18,25 @@ namespace WcfService
public class FederationSTSServiceHost : WSTrustServiceHost
{
internal const string BasePath = "LocalSTS.svc";
internal const string RelativePath = "transport";
internal static List<Tuple<Type, Binding, string>> EndpointList = new List<Tuple<Type, Binding, string>>
{
Tuple.Create(typeof(IWSTrust13SyncContract), GetBinding(), "wsHttp/wstrust13"),
Tuple.Create(typeof(IWSTrustFeb2005SyncContract), GetBinding(), "wsHttp/wstrustFeb2005"),
};

public FederationSTSServiceHost(params Uri[] baseAddresses)
: base(new SecurityTokenServiceConfiguration(), baseAddresses)
{
ConfigureService();
AddServiceEndpoint(typeof(IWSTrust13SyncContract), GetBinding(), RelativePath);
foreach(var tuple in EndpointList)
{
AddServiceEndpoint(tuple.Item1, tuple.Item2, tuple.Item3);
}
}

private Binding GetBinding()
private static Binding GetBinding()
{
var binding = new WS2007HttpBinding(SecurityMode.Transport);
var binding = new WSHttpBinding(SecurityMode.Transport);
if (HostingEnvironment.IsHosted)
{
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ namespace WcfService
{
internal class SelfHostSecurityTokenService : SecurityTokenService
{
public SelfHostSecurityTokenService(SecurityTokenServiceConfiguration configuration)
: base(configuration)
{
}
public SelfHostSecurityTokenService(SecurityTokenServiceConfiguration configuration) : base(configuration) { }

protected override Scope GetScope(ClaimsPrincipal principal, RequestSecurityToken request)
{
Expand All @@ -37,9 +34,8 @@ protected override Scope GetScope(ClaimsPrincipal principal, RequestSecurityToke

var scope = new Scope(request.AppliesTo.Uri.OriginalString, SecurityTokenServiceConfiguration.SigningCredentials)
{
TokenEncryptionRequired = false
//EncryptingCredentials = new X509EncryptingCredentials(SecurityTokenServiceConfiguration.ServiceCertificate),
//SymmetricKeyEncryptionRequired = true
TokenEncryptionRequired = false,
SymmetricKeyEncryptionRequired = false
};

if (string.IsNullOrEmpty(request.ReplyTo))
Expand Down
Loading

0 comments on commit 378a5b0

Please sign in to comment.