Configure WCF Service Virtual Directories to Allow Anonymous Access

When you enable WIF on an WCF service, WSTrustServiceHost turns on MEX endpoint automatic publishing for the service, so you must configure your service’s virtual directory to allow anonymous access. WSTrustServiceHost is typically associated with an STS, but non-STS endpoints might also be added to the service. WIF does not enable MEX on non-STS services. You can turn off enabling anonymous MEX by setting DisableWsdl to true, and you should do so in production settings to mitigate certain MEX attacks. Also note that WIF enables MEX on the same base addresses that are registered with the WSTrustServiceHost, so anonymous MEX is only enabled if an endpoint is registered with the "http" protocol, and MEX over HTTPS is only available if an endpoint is registered with the "https" protocol.

Some Claims and ClaimsIdentity Properties Not Serialized

The following properties are intended to be used by the relying party, so they are not serialized out on the wire, and setting them during token issuance will have no effect:

  • Claim.Issuer. The Issuer property is populated on receive by the IssuerNameRegistry’s return value for X509 and SAML tokens.

  • Claim.Properties. The Properties property is ignored by default and not serialized out on the wire.

  • ClaimsIdentity.Label. The Label property is intended to be populated on receive by relying party policy.

  • ClaimsIdentity.NameClaimType. The NameClaimType property is intended to be used on the receiving side to choose which claim value is used for IIdentity.Name.

  • ClaimsIdentity.RoleClaimType. The RoleClaimType property is intended to be used on the receiving side to choose which claim value is used for IsInRole() when issuing a token.

  • ClaimsIdentity.AuthenticationType. The AuthenticationType property is set on the receiving side when a token handler validates a token and indicates how the token was validated.

Thread Safety When Reserializing Bootstrap Tokens

When reserializing SAML bootstrap tokens (such as in an ActAs scenario) using multiple threads, you must synchronize your calls; otherwise, the tokens might become corrupted. For more information about ActAs, see Identity Delegation Scenario and Frequently Asked Questions.

ConfigureServiceHost

ConfigureServiceHost configures a Windows Communication Foundation (WCF) relying party with Windows® Identity Foundation (WIF). Use the overloads of this method to specify configuration details.

Secure Conversations

If you don’t want to establish secure conversation sessions between the token requestor and your STS, you must disable the secure conversation feature. Unlike the WsHttpBinding, the WSFederationHttpBinding class does not let you disable secure conversations. Instead, you must create a custom binding that replaces the secure session settings with a bootstrap. For an example of how to do this, see the client’s app.config file in the Web Service/ClaimsAwareWebService sample in the sample directory. The following example shows the relevant configuration.

  Copy Code
	<customBinding>
		<binding name="MyCustomBinding">
		<security authenticationMode="IssuedTokenForCertificate">
		</security>
<!-- other binding elements like httpTransport go here -->
		</binding>
	</customBinding>


The key point is not to use the SecureConversation authentication mode. For more information about how to perform this configuration in code, see How to: Disable Secure Conversations on a WsFederationHttpBinding.

Best Practices for ClaimsPrincipal.IsInRole

This consideration relates to a scenario in which you have configured multiple claim types and you want to use IsInRole to determine the access control. It is recommended that you not use multiple role claim types with the same claim values. Instead, you should use only one role claim type.

For example, suppose you have multiple role claim types configured: http://.../Role and http://.../Group. The incoming token contains Group:Editor. If your application calls IsInRole(“Editor”) it will return true because the token contains Group:Editor. Suppose, however, that you want your application to give access only if the token contains Role:Editor (in other words, Group:Editor should not be sufficient). WIF does not currently support this.

Alternatively, you can use the claims model directly and not use IsInRole.

SPNego Authentication Mode

SPNego is the default authentication mode on WsHttpBinding. SPNego is supported whether RequireCancellation is true or false. However, it is not supported when RequireCancellation is false, as this indicates cookie mode at the negotiate layer. Setting RequireCancellation to true indicates session mode at the negotiate layer, and this is supported. Also note that ClaimsAuthenticationManager is not invoked in the SSPI case.

http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod and http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationinstant claims are not generated for SPNego.

Finally, bootstrap tokens are not supported for SPNego. In this case, the bootstrap token collection is empty.

Cookie Mode SSPI Authentication Not Supported

Cookie mode SSPI authentication is not supported. There are two ways to get unsupported bindings that can perform SSPI authentication:

  1. Convert a WSHttpBinding into a custom binding and set RequireCancellation to false.

  2. Call SymmetricSecurityBindingElement.CreateSspiNegotiationBindingElement.

Quota Exceeded Exception When Using SAML2 Tokens that Contain ActAs Claims

If you try to use SAML 2 tokens that contain ActAs claims, you might receive a “quota exceeded” exception. This is because the ActAs claim can cause the SAML 2 token to exceed the 8K default token size imposed by Windows Communication Foundation (WCF). For more information, see. http://go.microsoft.com/fwlink/?LinkId=150815

How to Use SAML 2 Tokens

For an RP application that uses ASP.NET, you must set the default token type on the STS to SAML2 or modify the STS policy to correctly set the RST TokenType to SAML2 per request. The following code sample shows how:

  Copy Code
//
// When using standard WS2007FederationHttpBinding
//
WS2007FederationHttpBinding binding = new WS2007FederationHttpBinding();
binding.Security.Message.IssuedTokenType = Saml2SecurityTokenHandler.TokenProfile11TokenType;

For an RP application that uses ASP.NET, you must set the default token type on the STS to SAML2. You do not have to set anything on the RP application; it will accept any tokens it can process. The following code sample shows how:

  Copy Code
// In the SecurityTokenServiceConfiguration constructor, we can add:
this.DefaultTokenType = Saml2SecurityTokenHandler.TokenProfile11TokenType;

Security Token Service Issuer Name

Note that you should always set the STS issuer name to a valid and absolute, not relative, URI:

  Copy Code
SecurityTokenServiceConfiguration stsConfig = new SecurityTokenServiceConfiguration(“http://localhost:8081/STS”);
SecurityTokenService sts = new SecurityTokenService(stsConfig);

This is because, if an STS issues a managed card when the STS has not been configured to use an issuer name that is a valid URL, CardSpace will be unable to import the card.

Case Sensitivity Login Failure

To reproduce the login failure when cookie path does not match URL of final redirect, due to case sensitivity issue:

  1. Set up a passive federated ASP.NET relying party (RP) application that has a virtual directory that includes uppercase letters, such as “MyRP.”

  2. Try to access the RP with a URL in which the virtual directory is spelled with lower-case letters (for example, “myrp”). For example, you might code or configure a Security Token Service (STS) provider to post a token to the RP using such a URL.

  3. The client logon will fail.

This occurs because the cookie that is written to the client is never sent back to the Web application by the client’s browser, because the PATH attribute of the cookie has a different case than the requested URL. That is, the PATH attribute refers to the virtual directory as “MyRP”, whereas the requested URL is “myrp”. The PATH attribute is taken directly from the virtual directory name using AppDomainAppVirtualPath. Because the client's browser is case sensitive when matching cookie paths, the federated cookie is never sent back upon the subsequent redirect.

To avoid this issue, when you want to access the RP, make sure that the URL refers to the Web application content using the correct case.

SSL Certificate Validation Failure

To reproduce the SSL certificate validation fails when WinHTTP is not provided with proxy configuration issue:

  1. Set up an application that connects to a Web service that uses SSL. Have the application run as Network Service or Local System. Configure the application to connect by using a proxy server in the app.config file.

  2. The application will throw the following exception:

      Copy Code
    WebException: System.Net.WebException: Web service connection failed:
    The underlying connection was closed: Could not establish trust
    relationship for the SSL/TLS secure channel. --->
    System.Net.WebException: The underlying connection was closed: Could not
    establish trust relationship for the SSL/TLS secure channel. --->
    System.Security.Authentication.AuthenticationException: The remote
    certificate is invalid according to the validation procedure.
    

This occurs because the application provides .NET with the proxy configuration in the app.config file, but WinHTTP is not informed of the proxy configuration. This causes the requests for AIA/Intermediate Authorities during certificate chain validation to fail.

To avoid this issue, use either proxycfg.exe or the WinHttpSetDefaultProxyConfiguration function to configure the WinHTTP proxy to comply with the application’s app.config file.

WS-Trust Verbs

By default, an STS built with WIF supports only the “issue” verb. It does not expose the “renew”, “cancel”, or “validate” verbs as WSDL operations. You can customize this behavior by overriding IsOperationSupported.

FederatedPassiveSignIn.AutoSignIn Redirect

If you set AutoSignIn to true for the FederatedPassiveSignIn control, make sure that you set DestinationPageUrl to a different URL than your sign-in page. Otherwise, when a user successfully authenticates to an STS, the browser will go into an infinite redirection loop. This is because, if the user is redirected to the same page that originally sent them to the STS, the control sees that the current request is not a postback and does not contain a token. Therefore, it sends the user to the STS again.

IPrincipal and IClaimsPrincipal

When an application receives a request for service, there are two ways for it to discover who its caller is. The first is to use the IPrincipal and IIdentity classes. This approach is supported by both ASP.NET and WCF, and WIF is fully integrated with this model on both platforms so that the existing code can be used with the new claims-based identity model and authentication modes. WIF can expose values for a specific claim type as .NET Framework identity roles, so that that application code can use IsInRole for authorization. The application code or the administrator can select a claim type URI, and the .NET identity model will expose, as roles, all the values associated with that claim type that appear in the caller’s principal.

The second approach is to use the IClaimsPrincipal class provided by WIF. Unlike the .NET identity model, this class directly exposes the claims provided by WIF. This provides all available information about the caller. When you have enabled WIF, you should use IClaimsPrincipal. As a note, when WIF is enabled inside WCF, the WCF ServiceSecurityContext does not work for obtaining the caller’s identity and claims; the application code must use the IClaimsPrincipal to access the caller’s information. You can obtain the IClaimsPrincipal instance using Thread.CurrentPrincipal. This is available for every authentication type as soon as WIF is enabled for the WCF application.

Note:
You should not reference Thread.CurrentPrincipal during any event raised by WSFederationAuthenticationModule or SessionAuthenticationModule. Thread.CurrentPrincipal is set after the authentication process, whereas events are raised during the authentication process.

SessionSecurityToken Expiration Time

When the user chooses to issue cookies for their RP application, the lifetime of the corresponding SessionSecurityToken is set to the same length as the DefaultTokenLifetime property on the SessionSecurityTokenHandler. To change the lifetime of the token’s validity, please use plug in a custom SessionSecurityTokenHandler. WIF does not support setting the lifetime of a SessionSecurityToken though web.config or app.config.

WCF Authentication Flags Compatibility

Customers who depend on the WCF authentication flags listed below will find that the flags no longer have any effect. This will manifest itself in the form of scenarios breaking due to WIF enforcing stricter checks at the token handler level, or behavior changes where the validation mode setting is not honored. The following are some of the flags that are not supported or are replaced in WIF:

  1. ServiceHost.Credentials.IssuedTokenAuthentication

  2. ServiceHost.Credentials.ClientCertificate.Authentication

  3. ServiceHost.Credentials.UserNameAuthentication

Compatibility with IssuedTokenAuthentication.KnownCertificates

In WCF Web services that are WIF-enabled, if IssuedTokenAuthentication.KnownCertificates is not set, the framework defaults to the SimpleIssuerTokenResolver, which resolves any raw data SKIs that come in over the wire and fails on other SKI types, such as IssuerSerial. If IssuedTokenAuthentication.KnownCertificates is set, then the framework, by default, builds a token resolver from the KnownCertificates set. However, this resolver will fail raw data SKIs that are not in the KnownCertificates set. This is the current behavior as of this beta release.

Handling wtrealm and wreply

A SignIn request message sent to an STS must contain either a wtrealm or wreply parameter. The wtrealm should be used to make policy decisions. The wreply should not be blindly used as a redirect URL without first consulting policy to ensure that its value is trusted.

Certain Configuration Settings are Ignored

In the <tokenhandlerconfiguration> element, configuration settings at the <certificateValidation> level are ignored, whereas those at the <certificateValidator> level are honored. This is shown by the following configuration sample:

  Copy Code
<tokenHandlerConfiguration>
<!—The following settings are ignored -->
	<certificateValidation mode="ignored" revocationMode="ignored" trustedStoreLocation="ignored">
<! – The following settings are honored -->
		<certificateValidator type="honored" />
	</certificateValidation>
</tokenHandlerConfiguration>

If configuration settings are specified at both the <serviceConfiguration> and <securityTokenHandlers> levels, those at the <securityTokenHandlers> level are honored, whereas those at the <serviceConfiguration> are ignored. This is shown by the following configuration sample:

  Copy Code
<serviceConfiguration>
	<issuerNameRegistry type="ignored" />
	<serviceTokenResolver type="ignored" />
	<audienceUris>
		ignored
	</audienceUris>
	<certificateValidation>
		ignored
	</certificateValidation>
	<issuerTokenResolver type="ignored" />
	<securityTokenHandlers>
		<securityTokenHandlerConfiguration>
			<issuerNameRegistry type="honored" />
			<serviceTokenResolver type="honored" />
			<audienceUris>
				honored
				</audienceUris>
				<certificateValidation>
					honored
				</certificateValidation>
			<issuerTokenResolver type="honored" />
		<securityTokenHandlerConfiguration>
	</securityTokenHandlers>
</serviceConfiguration>

Do not re-use Channels Created with CreateChannelActingAs and CreateChannelOnBehalfOf

You should not re-use channels created with the CreateChannelActingAs or CreateChannelOnBehalfOf methods. Instead, use one channel per call.