Welcome to Windows Communication Foundation (WCF)
Top Tasks :

WCF Team Bloggers

Browse by Tags

All Tags » Messages » Security   (RSS)

  • Basing Authorization on the Message Body

    How do I use a field in the message to answer an authorization request in ServiceAuthorizationManager? There are two ways to go about doing this. The first makes use of a new feature in Orcas while the other is potentially more flexible and definitely requires more work. There’s a new overload for CheckAccess in ServiceAuthorizationManager that gives you a Message instance for the current request. This allows you to access the body contents by reading the message. Reading the message consumes it so you’ll need to replace the message when you’re done. You should be aware that this is going to be a significant speed bump unless you were already buffering messages. Even so, touching the body contents is almost guaranteed to take noticeably longer than you’re used to for performing authorization checks. public virtual bool CheckAccess(OperationContext operationContext, ref Message message); The other option is to insert a transformation step prior to ServiceAuthorizationManager being invoked. The transformation step takes the contents of the message and extracts the information needed for the authorization decision into a message header or property. This allows you to use ServiceAuthorizationManager exactly as before. Adding the transformation is a lot harder than overriding a method but you can potentially be doing other protocol work at the same time that also uses the contents of the message. You may be able to amortize some of the overhead of touching the message body in this way although in the worst case you’re no better off than with CheckAccess. Next time: Demanding Permissions Read More...
  • Securing Custom Headers, Version 2

    Last time we were looking at the problem of securing a dynamically generated message header . We saw one solution to that problem, which was to add a behavior that updated the protection level for the desired message part. That solution is quite simple but it isn't perfect. The execution of this behavior comes rather late. Anyone that inspects the service description in the meantime, such as for metadata generation, won't see the protection level that we want to use. How early can we make the update to the security settings? Well, potentially very early. We could subclass ServiceHost and override ApplyConfiguration to make the changes during creation of the host . That may even be too early as it prevents us from working with anything that is added to the service description through code rather than configuration. However, we could similarly make the changes some time after we get the service host object back but before it was opened. This would let us plug in before any behaviors started execution. The choice is yours. The downside of this method is that it is a more treacherous route to get to the message header. Starting from the service host we need to get the endpoint that we're going to modify (usually by contract or address). From the endpoint we can get the operation by action name. From the operation we can get the right message by name. The default names are canonically derived from the operation action and direction. Unlike before, separating incoming and outgoing messages here is a lot murkier. From the message though, we can refer to the message header in the same way and set its protection level. Here's all of that in code using some example values. ServiceEndpoint endpoint = host.Description.Endpoints.Find( typeof (IService)); OperationDescription operation = endpoint.Contract.Operations.Find( "Action" ); MessageDescription message = operation.Messages.Find( "http://tempuri.org/IService/ActionResponse" ); MessageHeaderDescription header = message.Headers[ new XmlQualifiedName( "aheader" , "http://tempuri.org/" )]; header.ProtectionLevel = ProtectionLevel.Sign; Next time: Keeping Traces Up to Date Read More...
  • Securing Custom Headers, Version 1

    I'm securing messages using SOAP security but I also have some message headers that are generated dynamically at runtime. How do I protect the generated message headers as well? If you've used SOAP security, then you've probably done it by decorating your messages with attributes that describe what the protection level is for various message parts. Obviously there's a problem here trying to take that approach with dynamically generated message headers. Since these message headers aren't a part of the declared message, there's nothing in the contract that you can decorate. We're going to look at two ways of solving this problem. For both articles, I'm only going to talk about protecting messages by signing. It is trivially easy to add encryption in if you want. The same is true for protecting headers on incoming versus outgoing messages as well. The first approach we're going to look at is to modify the security settings through binding parameters. The binding parameters contain the protection requirements of the contract. The protection requirements contain the list of headers. That gives us a two-step approach to accessing the list of headers. Since we need to change the protection requirements before the service is started, we'll insert a contract behavior to make the adjustments. public class SignMessageHeaderBehavior : Attribute, IContractBehavior { string action; string header; string ns; public SignMessageHeaderBehavior( string header, string ns, string action) { this .header = header; this .ns = ns; this .action = action; } public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { ChannelProtectionRequirements requirements = bindingParameters.Find<ChannelProtectionRequirements>(); XmlQualifiedName qName = new XmlQualifiedName(header, ns); MessagePartSpecification part = new MessagePartSpecification(qName); requirements.OutgoingSignatureParts.AddParts(part, action); } public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime) { } public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.DispatchRuntime dispatchRuntime) { } public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint) { } } Now, you've got a behavior that can at run time add a new message header Read More...

Copyright © 2006 Microsoft Corporation. All Rights Reserved. | Terms of Use | Privacy Statement | Contact Us