|
|
Browse by Tags
All Tags » Answers » Transport Security (RSS)
-
How do I use username credentials with IPSec? I'm told that I need to turn on security but my connection is already secure. WCF only permits username tokens to be transmitted over a binding that's secure. If a username and password are transmitted without some way of obscuring their values, then that essentially allows anyone that can read the message to steal those credentials. There are many meanings that could be applied to the word secure, but in this case the definition of secure is only that the binding promises to protect the data that's transmitted by providing confidentiality. IPSec is a way to provide security that's external to service. It can be used together with a binding that doesn’t ordinarily provide security, but the binding has no way of knowing that its security has been upgraded. The mechanism for making security promises on a binding is ISecurityCapabilities. This interface defines the supported protection levels for transmitting messages as well as various other security properties. When security is externally provided, you can use this interface to pretend like the binding is more secure than it really is so that the security capabilities match the actual environment. When using IPSec, requests and responses can be confidential and tamper-proof. This corresponds to a protection level of EncryptAndSign. This is implemented by wrapping the channel to provide a custom set of security capabilities from GetProperty. You'll want to get the ISecurityCapabilities from the underlying channel and then take the maximum of those capabilities together with the capabilities of your external security. Next time: The Pipe DACL Read More...
|
-
Is it possible to configure the protection level for message parts at runtime? Only certain configurations make doing this particularly easy. When using transport security with Windows credentials, the WindowsStreamSecurityBindingElement allows you to directly set the protection level (changing the protection level when using SSL doesn't make as much sense due to the way SSL works). On the other hand, there's no equivalent facility for message security, which will always give you both encryption and signing if you haven't explicitly set the protection level on the contract. There are a few ways to attack this lack of configurability: configure a custom service host to override the contract description during ApplyConfiguration configure a behavior to modify the contract description when behaviors are applied configure a behavior to modify the channel protection requirements when the security channel is instantiated The first approach is a very indiscriminate way to get the job done. Modifying the entire service is almost certainly not what you want to do, so you'd need some way to describe the scope of specific message parts that you want to modify. Behaviors can be much more targeted. The second approach has the hidden downside that modifying the contract description at one endpoint can potentially (depending on order of execution) modify the contract description for other endpoints. This also is almost certainly not what you want to do. Finally, both the second and third approaches have downsides due to being implemented with behaviors. User behaviors are executed after the security validation behavior that is run as part of the service start up. This means that you're unable to declare a protection level on the contract and then later reduce it in the behavior unless the binding is capable of supporting the originally specified protection level. Also, the results of modifying a contract in a behavior don't get reflected in metadata, which makes a variety of tasks harder. In short, none of these options are particularly good. The third approach is probably the most workable although it does suffer a number of downsides. You can base this approach on the following bit of code. public class ProtectionLevelEndpointBehavior : IEndpointBehavior { public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { ChannelProtectionRequirements requirements = bindingParameters.Find<ChannelProtectionRequirements>(); // Read More...
|
-
How do I customize the exception text sent back from a custom password validator? If you've looked at the documentation for UserNamePasswordValidator, then the instructions tell you to implement the validator by overriding the Validate method and throwing a SecurityTokenValidationException if you don't like the username and password pair that was provided. A failed validation attempt results in an exception back on the client that is fairly generic. An error occurred when processing the security tokens in the message . Being generic is the correct thing to do most of the time because you don't want to volunteer unnecessary information in your security responses. Subtle differences in how the application behaves can give an attacker hints about the parts of their input that passed validation and the parts of their input that failed validation. However, if an attacker can't use the diagnostic information to their advantage, then you may want to provide more information to make debugging easier. Changing this exception message is relatively easy to do although hard to discover. In your Validate method, rather than throwing a security exception, you can instead throw a FaultException with a custom message. That custom message will be passed back to the client application although the details of the fault will not. public class MyUserNameValidator : UserNamePasswordValidator { public override void Validate( string userName, string password) { // validation logic if (validationFailed) { throw new FaultException( "Here's a description of why validation failed" ); } } } Next time: Configuring Protection Level Read More...
|
-
What are the rules for when a client needs to support Active Directory integration for sending to an MSMQ queue? The circumstances may seen mysterious for when you need the client to be joined to a domain to take advantage of Active Directory integration, but the rules turn out to actually be pretty simple. This should help you avoid seeing errors like the following: Binding validation failed because the binding's MsmqAuthenticationMode property is set to WindowsDomain but MSMQ is installed with Active Directory integration disabled. The channel factory or service host cannot be opened. The authentication mode of the MSMQ transport and the protection level of the message are interrelated, and these both are related to when you need to be using Active Directory. Rather than making you assemble the various combinations as a logic puzzle, I've digested the results into a table explaining when Active Directory is required to pass validation. Protection None Protection Sign Protection EncryptAndSign Authentication None Not required Not supported Not supported Authentication Certificate Not supported Not required Required Authentication WindowsDomain Not supported Required Required The same rules apply to both sides so you're covered for the explanation of the service as well. Next time: Customizing Exceptions for Validation Read More...
|
-
How often does authorization occur? Authorization is typically scoped to either messages or sessions. When authorization is scoped to messages, then an authorization request occurs each time a message is sent. When authorization is scoped to sessions, then an authorization request occurs at the start of the session and all of the messages that are transmitted on the session share the authorization outcome. The exact timing of the authorization request can vary depending on whether authorization happens when open is called on the channel or when send is called on the channel for the first time. You can only have authorization scoped to sessions if you have a sessionful channel that incorporates session-based security. TCP is an example of a transport channel that is sessionful and supports session-based security through SSL. Message security is an example of a layered channel that is sessionful and supports session-based security through conversation mechanisms. There are many other channels that are either secure or sessionful but don't have session-based security. Next time: Sharing Contracts Across Services Read More...
|
-
How do I write a service that gives clients the option to choose between different security mechanisms for protecting a service call? For example, how can I allow clients to choose between certificates and passwords? I think that if the example choice had been between message security and transport security, then many people would have immediately suggested having two bindings for the different security mechanisms hosted on two different endpoints of the same service. There's no reason why you couldn't use the same strategy in this case where the alternatives are two different kinds of message security. The binding configuration process involves a series of choices, including choosing from enumerations of security mechanisms. It's difficult to craft configurations that accept a wide range of valid formats at the same time. This choice of configurations can of course also be made less apparent by moving the choice farther away from the service endpoint. If you create an abstraction by defining an intermediate credential type, then the service endpoint is simplified by only accepting the intermediate credentials and the choice is offered by giving multiple mechanisms to obtain those intermediate credentials. Next time: Trace Transfer Read More...
|
-
Can I secure a message without having to buffer the message in memory? The answer to this question is yes and no, depending on what the word secure is supposed to mean. There are differences between the operation of transport-level security and message-level security, as well as potentially differences between particular security algorithms. Transport level security algorithms have historically composed very well with streaming. SSL does an initial handshake to exchange security information and then sets up a security session between the two parties. The security session doesn't place any significant requirements on having an available buffer of message content and the session lasts until one of the parties decides to disconnect or renegotiate the connection. Message level security algorithms generally don't attempt to optimize for transmission efficiency as compared to transport level security algorithms. The signing and encryption facilities of WS-Security require an examination of the complete message contents before the message can be secured. This obviously does not compose with streaming although it doesn't particularly impact pseudo-streaming approaches, such as chunking. Message level security provides capabilities not found in transport level security, such as protection over multiple hops, but these features do not come for free in terms of performance. Next time: Supporting Multiple Security Mechanisms Read More...
|
-
How do I enable Kerberos authentication for my web service? Kerberos is a very good authentication protocol to use when you're joined to a Windows domain. It is intended to work through simple configuration, but using Kerberos for network authentication sometimes turns out to be harder than it should. There are two fundamental steps that you need to take when setting up your service for Kerberos: Enable Integrated Windows Authentication for your website in IIS. Configure your WCF service binding to have Windows credentials so that you can get the Negotiate protocol on the wire. These basics were exactly what I covered a few days ago when talking about turning off anonymous access . Now, I have some troubleshooting tips in case you think that you have Kerberos enabled but are either getting an error or getting NTLM instead of Kerberos. I'm going to recommend that you get some network monitoring software so that you can look at the HTTP headers. It's possible to look at the HTTP headers in other ways, but using an external program for network sniffing makes it less likely that you accidentally "fix" the problem by setting up your monitoring program differently than your actual service. Being able to look at the HTTP headers lets you see whether Kerberos or NTLM is being offered on the wire. One of the common reasons for Kerberos to be skipped is an issue with the principal name. The client has to specify a user or service principal name as the target when connecting to the service. The service needs to have its service principal name registered when receiving requests. When you first set up a web server, service principals are registered for standard accounts like System and Network Service. If you're using a non-standard account or the configuration has been changed a lot over time, you may be in a state where you have zero or multiple service principals, either of which will cause Kerberos to fail. Another issue with changing configurations is that IIS allows you to configure the authentication providers for an application pool. This is the NtAuthenticationProviders setting. Either the default value or explicitly setting that variable to "Negotiate,NTLM" should work, but I've seen some configurations that had this set to support NTLM only. Next time: Choosing a Message Size for Buffered Copies Read More...
|
-
How do I prevent clients from accessing my service anonymously? I've changed the settings in IIS from Anonymous Access to Integrated Windows Authentication. However, now I'm getting the error message: "Security settings for this service require 'Anonymous' Authentication but it is not enabled for the IIS application that hosts this service." Disabling anonymous access requires coordinating the settings in IIS and in your service configuration. Those two sources must be in agreement about whether anonymous access is expected. IIS is already using Windows authentication in this case, so let's look at what needs to happen to the service configuration file. I'm assuming that this is IIS6 so the only network transport we're talking about here is HTTP. There are two cases depending on whether you want the protocol that gets exposed to be HTTP or HTTPS. The simplest is to keep using HTTP since that's probably what you were using if anonymous access was allowed in the past. To switch off anonymous access with HTTP, you need to set the security mode to TransportCredentialOnly. < basicHttpBinding > < binding > < security mode ="TransportCredentialOnly" > < transport clientCredentialType ="Windows" /> </ security > </ binding > </ basicHttpBinding > Note that TransportCredentialOnly is not supported for every binding (in this case we're using BasicHttp). For WSHttp, the only choice is going to be to use HTTPS. To switch off anonymous access with HTTPS, you need to set the security mode to Transport. < wsHttpBinding > < binding > < security mode ="Transport" > < transport clientCredentialType ="Windows" /> </ security > </ binding > </ wsHttpBinding > Other bindings can be made to work in this situation as well, including custom bindings. I'm just showing you the most common examples. The key in both cases though is that we're getting transport security with the right kind of credentials associated. Next time: Writing Binding Element Essentials Read More...
|
-
How do I control whether the transport signs and encrypts messages? This answer ties into the article I wrote a few weeks ago on describing channel security capabilities . If you don't remember about protection levels and security capabilities, then you should read that article first. The service and operation contract attributes include a field, called ProtectionLevel, for describing the minimal level of protection that should be applied to messages. If you have security in the channel stack and don't specify any settings, then the default is to both sign and encrypt messages. If the channel stack does not support the requested protection level, for instance HTTP supports neither encryption nor signing, then you'll get an exception saying that the binding you've chosen is incompatible with the specified security settings. If the channel stack does support that protection level, then you are guaranteed to receive at least the minimum level of protection on messages. What does that mean? Message security and transport channels are going to combine to provide at least the minimum level of protection. Let's make the picture simpler by saying that message security is not being used at all. We have a channel stack that just provides transport security. The transport security binding element has an additional configuration knob that lets you specify the target protection level, also labeled ProtectionLevel. Assume that we're being reasonable here and say that the transport protection level is at least the contract protection level. Then, the transport channel will attempt to provide a protection level that is no greater than the target protection level. Some transports do not have flexibility in the protection level that they provide. SSL security, such as with HTTPS, always provides encryption and signing. There's no way to throttle that security method back and so the transport protection level knob is ignored. Windows security, such as with TCP, does permit throttling the protection level. If the service contract specifies signing only, you're using TCP with Windows security, and you've set the transport protection level to signing only as well, then everything aligns for you to get signing only. Note that if you want neither signing nor encryption, then the easiest way to do this is to simply replace your transport with one that does not supply security. Next time: You Can't Fake Correlation Read More...
|
-
I occasionally see people asking how they can fake the security capabilities of a binding. These questions often start off with "I'm getting an error message that a message's required protection level is not being met". Now, I'm not precisely sure why you'd want to fake the security capabilities in this case. After all, the application developer is in charge of both specifying the protection requirements of the messages and choosing what channels to use. If they're getting this error message, then it more than likely means that this helpful check has detected a problem somewhere in their design. There are a few rare reasons why you'd want to fake this, but they mainly involve transmitting over specially secured networks. However, it turns out that faking security capabilities is exactly the same as legitimately specifying the capabilities of a custom channel so I might as well explain that! Security capabilities are found by querying the channel stack with GetProperty for an instance of ISecurityCapabilities. This call should be supported on the binding element of channels that implement message or transport security. Transport channels should respond with something, even if it is to say that they don't support any kind of security. Everyone else can just delegate the call to their inner channel (which is typically what you do by default for any type you don't know about). public interface ISecurityCapabilities { ProtectionLevel SupportedRequestProtectionLevel { get; } ProtectionLevel SupportedResponseProtectionLevel { get; } bool SupportsClientAuthentication { get; } bool SupportsClientWindowsIdentity { get; } bool SupportsServerAuthentication { get; } } The fields here should be self-explanatory, you either support a particular feature or you don't, but let's look at examples from some of the existing channels. HTTP doesn't support any protection on requests and responses, neither encryption nor signing. HTTP supports client authentication when in any security mode but Anonymous. It only supports server authentication when using Negotiate security. Windows identities are supported whenever client authentication is. On the other hand, HTTPS provides both encryption and signing for both requests and responses. HTTPS always does server authentication. It supports client authentication and Windows identities whenever HTTP would plus whenever client certificates are turned on. You can quickly get a sense of the differences between HTTP and HTTPS by looking at Read More...
|
-
Here's a quick list of things to try when debugging a non-functioning SSL server certificate. Has the certificate expired or been revoked? Does the MMC Certificate Manager say that the certificate is valid? Is the certificate in the LocalMachine store? Have you registered the certificate to the address and port of your service? Does the registered thumbprint match the SHA1 thumbprint of the certificate? Does the certificate address match the address in your service URI? Is the root certificate valid and in the trusted root store? Is the certificate revocation server reachable and functioning? Next time: When to Wait for Messages Read More...
|
-
After switching from message security to transport security, I'm seeing a bunch of weird protocols being used in message exchanges (even when the credentials are still at the message level). What's going on? Also, why do I need to provide a certificate for the server? HTTPS doesn't make me do this. WCF has several negotiation protocols that it can use to exchange credentials. When using message security, these protocols are typically implemented at the SOAP level running through the WS-Security family of standards. With transport-level security, the client and service have to securely exchange credentials on their own. The negotiation protocol that transport security uses is going to depend on the type of identifying token being exchanged. For example, the exchange of Windows credentials has a different protocol than the exchange of UserNamePassword credentials. The details of the individual negotiation protocols aren't relevant here because they all ultimately provide transport protection of the exchange (although it is simple to find the details of protocols like SPNego). A certificate is needed when the protocol must authenticate the service before having a secure channel to send the token. Unless you have a scheme similar to that of SSL-enabled web sites, you need some out-of-band way of providing that certificate to the client. Next time: Avoiding OneWay Deadlocks Read More...
|
-
I have a service that uses Windows authentication and want to impersonate the caller in one of the service operations. How should I configure the client and service? There are a couple of things you need to do here to make this work. On the client side, you need to give the client proxy your Windows credentials and permit it to perform the impersonation. The exact level of impersonation you need is something determined by your application. I’m using plain old Impersonate level impersonation in this example. client.ClientCredentials.Windows.ClientCredential.Domain = "MYDOMAIN" ; client.ClientCredentials.Windows.ClientCredential.UserName = "User" ; client.ClientCredentials.Windows.ClientCredential.Password = "Password" ; client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation; Your service process needs the SeImpersonatePrivilege. Your operation needs to perform the impersonation. If you just want to impersonate for part of the operation, you can scope the impersonation block. using (ServiceSecurityContext.Current.WindowsIdentity.Impersonate()) { ... } You’d probably want to have some error handling for that block. If you want to impersonate for all of the operation, you can add an attribute to modify the operation behavior. [OperationBehavior(Impersonation = ImpersonationOption.Required)] Finally, you can add a service behavior to instruct the service to impersonate the caller for all operations when allowed. host.Description.Behaviors.Find<ServiceAuthorizationBehavior>().ImpersonateCallerForAllOperations = true ; Next time: Use OneWay for Long-Running Operations Read More...
|
-
I’m trying to use a Certificate credential with security mode TransportWithMessageCredential. Certificate credentials were working with transport security but now my clients can’t connect. Why isn’t this working? This one is fairly quick to diagnose if you look at what your service is telling you. I’ve set up a service with the WSHttpBinding and the security mode set to TransportWithMessageCredential. What’s probably gone wrong is that the configuration is setting the transport client credential type to Certificate. binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate; Let’s look at what the service metadata says that is doing. < wsHttpBinding > < binding name ="WSHttpBinding_Service" closeTimeout ="00:01:00" openTimeout ="00:01:00" receiveTimeout ="00:10:00" sendTimeout ="00:01:00" bypassProxyOnLocal ="false" transactionFlow ="false" hostNameComparisonMode ="StrongWildcard" maxBufferPoolSize ="524288" maxReceivedMessageSize ="65536" messageEncoding ="Text" textEncoding ="utf-8" useDefaultWebProxy ="true" allowCookies ="false" > < readerQuotas maxDepth ="32" maxStringContentLength ="8192" maxArrayLength ="16384" maxBytesPerRead ="4096" maxNameTableCharCount ="16384" /> < reliableSession ordered ="true" inactivityTimeout ="00:10:00" enabled ="false" /> < security mode ="TransportWithMessageCredential" > < transport clientCredentialType ="None" proxyCredentialType ="None" realm ="" /> < message clientCredentialType ="Windows" negotiateServiceCredential ="true" algorithmSuite ="Default" establishSecurityContext ="true" /> </ security > </ binding > </ wsHttpBinding > Hmm, the transport client credential type seems to be ignoring the setting and the message client credential type is Windows. What’s going on is that TransportWithMessageCredential only uses the message security credentials. The transport (HTTPS in this case) is locked to anonymous authentication and the message credentials are using Windows because that’s the default if you don’t change any of the settings. The mismatch between Windows and Certificate credentials are why the clients are failing. We can fix this by changing the client credential type line to set the message security credentials instead. binding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate; Now, the security block in the metadata gives us exactly what we want. < security mode ="TransportWithMessageCredential" Read More...
|
|
|
|