|
|
Browse by Tags
All Tags » Service Model » Security (RSS)
-
This article is primarily an introduction on protecting message data since the topic overall seems to cause some confusion. The source of confusion is what it means for a service to define a contract for protecting data. Data protection flows from two different directions and at a variety of different scopes. The service can define a minimum standard of protection at various contract scopes. Service contracts cover all of the application data exchanged by the service Operation contracts cover all of the application data exchanged for that particular operation Message and fault contracts cover all of the application data contained in those particular messages Message body and message header contracts cover those particular parts of the message This minimum standard appears as the ProtectionLevel on a contract and comes in three flavors: no protection, protected by digital signing, and protected by encryption (the use of encryption implies a signature as well). Signing prevents people from tampering with the messages while encryption prevents people from reading the messages. These contracts define the application messages that are exchanged. Depending on the protocols you make use of, any number of infrastructure headers or messages may need to be inserted into the data stream to facilitate the exchange of your application messages. This infrastructure data can have its own independent rules for protection. The ProtectionLevel truly is a minimum standard. It is ok for your application to receive messages that are protected better than the minimum standard defines. You may even send messages that are protected better than the minimum standard due to the other direction for flowing data protection. Data can be protected at the wire level by using security integrated with the network transport. For example, if you send data using HTTPS, then there is a level of protection that HTTPS must apply to your messages to transport them even if your contract specified a lower standard. The net protection level is the maximum of that provided by the service and provided by the transport. As long as for every piece of data at every scope that maximum is greater than your minimum standard, then everything works. If that maximum fails to meet your minimum standard, then the service will refuse to send or receive those messages. Next time: Embedding Arbitrary XML in Faults Read More...
|
-
When writing your own service authorization manager, you override the CheckAccess or CheckAccessCore methods to put in your logic for granting access. CheckAccess returns a boolean, which means that the options for expressing yourself are limited. If the result is true, then access is granted. If the result is false, then access is denied. However, you can actually be much more expressive if you'd like. If you trace through the authorization process a bit, then you'll see that returning false simply translates into the infrastructure throwing an exception. That exception is a FaultException that represents a sender fault for failing to properly authenticate. A little bit of thinking shows that rather than returning true or false, you could instead throw your own fault exception. It turns out that your fault exception does get propagated through, just like the system one, and a FaultException lets you be a lot more verbose than a boolean. Other types of exceptions will also get through although I don't recommend getting too adventurous. Being expressive is an advantage for the sender but a liability for the receiver. The receiver actually has to handle what you throw at it and try to do something intelligent with it. As you become more creative as a sender, receivers become less likely to actually do what you want them to. Next time: Reading Messages for Validation Read More...
|
-
How do I restrict access to an operation to particular Windows users? There are three standard ways of doing something in WCF: through code, through attributes, and through configuration. Let's try to solve the problem using each of these methods. Restricting access through code is done by creating a custom ServiceAuthorizationManager. Restricting access to a service operation could be done this way by looking up the service operation during the access check and comparing the caller's SID to the list of approved users. This method seems pretty clunky because it brings in a lot of service machinery unrelated to the service operation we want to secure. However, this method also seems pretty flexible because we can be very creative about how the authorization is performed if we want to go beyond simply evaluating membership. Restricting access through attributes is done by making PrincipalPermission demands. Restricting access to a service operation could be done this way by decorating the service operation with role or user based demands. The best practice recommends using roles instead of specific users because it helps with administration, which is probably good advice for all of these approaches. Using principal permissions requires actually having the right principal for the current thread. Some extra code may end up being required anyways if the client invocation doesn't propagate the right kind of information. Restricting access through configuration is done by setting up an external authorization provider. When in compatibility mode, there is some handy functionality provided by the ASP.NET pipeline to provide authorization integrated with ASP.NET membership providers. Even without ASP.NET though, the generic Authorization Manager can be used to manage and provide roles. I like using the attributed-based method but that's because I don't like to type a lot of code and because I rarely need to worry about deploying services on multiple systems. Each of the methods has its own strengths and weaknesses so there isn't a universal choice that's best for everyone. Next time: Suppressing Transactions During an Operation Read More...
|
-
How do I figure out during dispatch whether a request is destined to be a metadata request or a normal application request? The reason you might care whether a request in flight is for metadata or not is because of security policy. You might want to permit lots of people to access your metadata but be very strict about who can call application methods. If you're a security routine that intercepts all sorts of different calls, then you need to know what type of call is currently happening to make the right decision. Otherwise, you don't know who to apply scrutiny to and who to just let in. In the context of the currently in flight operation, there are three pieces of data that will help you figure this out. If you see all three signs, then you know that the request is going to be for metadata retrieval. Check the contract name of the endpoint that the current operation is being dispatched to. It should be IMetadataExchange. Just in case someone defines a different contract with the same name, also check the contract namespace. It should be http://schemas.microsoft.com/2006/04/mex. Finally, check the action of the operation. If it's an operation that does metadata transfer, then the action should be http://schemas.xmlsoap.org/ws/2004/09/transfer/Get/. Next time: Silent Security Failures Read More...
|
-
What does adding an identity to a service endpoint do in configuration? When I tried it, nothing happened. The questioner is asking about supplying an endpoint identity in the configuration of a service. Here's the configuration element we're talking about, with some considerable editing to keep the example simple. < service > < endpoint address ="..." binding ="..." bindingConfiguration ="..." contract ="..." > < identity > < servicePrincipalName value ="name" /> </ identity > </ endpoint > </ service > This configuration on the service doesn't actually change any runtime behavior. Clients will connect and function properly regardless of what the setting says. Instead, this value is used when advertising the service in metadata. Clients are suggested to use the advertised service identity unless someone comes along and supplies a different identity for the client configuration. That means you shouldn't just make up a value for the service configuration. The service runs with a particular identity and putting a value here does not change what that identity is. Either make sure the configuration matches the service or don't include this value to avoid tripping up clients that make use of metadata. Next time: Using Supporting Tokens Read More...
|
-
I'm setting up a custom principal for the current thread based on the received messages, but the principal gets reset before the service operation is called. How do I stop this from happening? What's likely happening here is that the PrincipalPermissionMode is still set to its default value. Most people don't want to get involved with how the current principal is chosen. Most people don't even want to get involved with how the current principal is consumed. As long as WCF sets things up to grant a reasonable set of permissions based on the caller, most people don't want to think about authorization. On the other hand, some people care very deeply how the current principal is chosen. For example, if you have your own role based system for authorization, then you will want to get involved in the process. That's why WCF gives you a variety of options for controlling how the principal gets established. The ServiceAuthorizationBehavior includes a setting called PrincipalPermissionMode to control setting the current principal. By default, the PrincipalPermissionMode is set to UseWindowsGroups. Your other options are to use ASP.NET roles, provide a callback for establishing a custom principal, or disable the automatic update to CurrentPrincipal by the service. Since this case already has some code to set the current principal, the right way to make that work is to disable the automatic update by setting PrincipalPemissionMode to None. Next time: Tradeoffs of IIS Hosting Read More...
|
|
|
|