This topic discusses design considerations.
- Best Practices for
- Case Sensitivity
Configuration Settings are Ignored
- Configure WCF
Service Virtual Directories to Allow Anonymous Access
- Cookie Mode SSPI
Authentication Not Supported
- FederatedPassiveSignIn.AutoSignIn Redirect
- Handling wtrealm and
- How to Use SAML 2
- IPrincipal and
- Quota Exceeded
Exception When Using SAML2 Tokens that Contain ActAs Claims
- Security Token Service
- SessionSecurityToken Expiration
- Some Claims and
ClaimsIdentity Properties Not Serialized
- SPNego Authentication
- SSL Certificate
- Thread Safety When
Reserializing Bootstrap Tokens
Authentication Flags Compatibility
- Do not
re-use Channels Created with CreateChannelActingAs and
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
Issuerproperty is populated on receive by the IssuerNameRegistry’s return value for X509 and SAML tokens.
- Claim.Properties. The
Propertiesproperty is ignored by default and not serialized out on the wire.
- ClaimsIdentity.Label. The
Labelproperty is intended to be populated on receive by relying party policy.
- ClaimsIdentity.NameClaimType. The
NameClaimTypeproperty is intended to be used on the receiving side to choose which claim value is used for
- ClaimsIdentity.RoleClaimType. The
RoleClaimTypeproperty 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
AuthenticationTypeproperty 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 configures a Windows Communication Foundation (WCF) relying party with Windows® Identity Foundation (WIF). Use the overloads of this method to specify configuration details.
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.
<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
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
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
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:
- Convert a
WSHttpBindinginto a custom binding and set RequireCancellation to false.
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:
// // 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:
// 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:
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:
- Set up a passive federated ASP.NET relying party (RP)
application that has a virtual directory that includes uppercase
letters, such as “MyRP.”
- 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.
- 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:
- 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
- The application will throw the following exception:
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.
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.
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
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
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
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:
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
element, configuration settings at the
<certificateValidation> level are ignored,
whereas those at the
level are honored. This is shown by the following configuration
<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
<securityTokenHandlers> levels, those at the
<securityTokenHandlers> level are honored,
whereas those at the
ignored. This is shown by the following configuration sample:
<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.