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
- ConfigureServiceHost
- Cookie Mode SSPI
Authentication Not Supported
- FederatedPassiveSignIn.AutoSignIn Redirect
- Handling wtrealm and
wreply
- How to Use SAML 2
Tokens
- IPrincipal and
IClaimsPrincipal
- Quota Exceeded
Exception When Using SAML2 Tokens that Contain ActAs Claims
- Secure
Conversations
- 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
- WS-Trust
Verbs
- Do not
re-use Channels Created with CreateChannelActingAs and
CreateChannelOnBehalfOf
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 forIIdentity.Name
.
- ClaimsIdentity.RoleClaimType. The
RoleClaimType
property is intended to be used on the receiving side to choose which claim value is used forIsInRole()
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:
- Convert a
WSHttpBinding
into a custom binding and set RequireCancellation to false.
- 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:
- 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
app.config file.
- 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:
- ServiceHost.Credentials.IssuedTokenAuthentication
- ServiceHost.Credentials.ClientCertificate.Authentication
- 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.