This topic discusses design considerations.
Best Practices for ClaimsPrincipal.IsInRole
Case Sensitivity Login Failure
Certain Configuration Settings are Ignored
Compatibility with IssuedTokenAuthentication.KnownCertificates
Configure WCF Service Virtual Directories to Allow Anonymous Access
Cookie Mode SSPI Authentication Not Supported
Handling wtrealm and wreply
How to Use SAML 2 Tokens
IPrincipal and IClaimsPrincipal
Quota Exceeded Exception When Using SAML2 Tokens that Contain ActAs Claims
Security Token Service Issuer Name
SessionSecurityToken Expiration Time
Some Claims and ClaimsIdentity Properties Not Serialized
SPNego Authentication Mode
SSL Certificate Validation Failure
Thread Safety When Reserializing Bootstrap Tokens
WCF Authentication Flags Compatibility
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.
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:
Issuerproperty is populated on receive by the IssuerNameRegistry’s return value for X509 and SAML tokens.
Propertiesproperty is ignored by default and not serialized out on the wire.
Labelproperty is intended to be populated on receive by relying party policy.
NameClaimTypeproperty is intended to be used on the receiving side to choose which claim value is used for
RoleClaimTypeproperty is intended to be used on the receiving side to choose which claim value is used for
IsInRole()when issuing a token.
AuthenticationTypeproperty is set on the receiving side when a token handler validates a token and indicates how the token was validated.
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.
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://.../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 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/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 is not supported. There are two ways to get unsupported bindings that can perform SSPI authentication:
WSHttpBindinginto a custom binding and set RequireCancellation to false.
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
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;
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.
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.
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 app.config file.
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.
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 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.
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.
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:
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.
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.
<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:
<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
<serviceConfiguration> are 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>
You should not set any property on the HTTP modules (ClaimsAuthorizationModule, ClaimsPrincipalHttpModule, SessionAuthenticationModule, or WSFederationAuthenticationModule) in the
Application_Start event handler. This is because the handler is called only once, but multiple instances of the HTTP modules might be created, in which case their properties are not set. Instead, you should set their properties in configuration.