The configuration of messaging security on the server side is based on the client-side configuration, in that a service can also be a client to another service. The server-side configuration adds to the information in the client configuration, by specifying:
Required Accepting Authentication Mechanism
This feature allows a Web service to accept only requests from authenticated users. In the scope of WSO2 SOA Enablement Server terminology, it is used to specify the required accepting authentication mechanisms. Default accepting mechanisms are a part of a global security configuration. These mechanisms can be overridden by specific Web service endpoint configurations.
Identity Associations
The service endpoint configuration is capable of associating an identity with the Web service endpoint. At most one identity can be used per authentication mechanism. An associated identity can be also used to authenticate a service to a client, as it is in the case of the default configuration of WS-Security authentication mechanism.
Authorization Requirements
The service endpoint configuration is able to set authorization requirements for incoming calls. If toggled on, every exposed method of a Web service becomes protected, to allow access only to authorized users.
It is possible to specify many default accepting authentication providers, and one initiating provider for a Web service. Accepting providers are used to express requirements for authentication of Web service clients. The default accepting authentication providers are used for all services that do not use their own custom configuration. The initiating provider is used in the case that a service is a client of another service. These providers can be set using ProvidersManager. For more information, please see Providers Manager.
The ProvidersManager tool facilitates the specification of different accepting and initiating providers for a particular Web service endpoint, thus overriding the defaults.
This tool can also associate identities with a Web service and turn on access control, or authorization checks, for clients invoking a Web service. These features are also available on the WSO2 SOA Enablement Server Administration Console. For more information, please see WSO2 SOA Enablement Server Management Console.
The server-side code can contain the same code lines used on the client side. There is no difference in the usage, but the semantics differ slightly. First, the Current instances are scoped to the Web service endpoints. In each Web service instance, its particular endpoint receives a different Current instance. The initiating provider on the server side is the same as the current provider on the client side. Also, the server and client side Current instances are more tightly coupled together.
Settings of credentials on the server Current causes the setting of credentials on the client Current. Only the server Current can be used to associate an identity for both incoming and outgoing communication. If you set credentials through the client Current, they are not used for server side Current.
The server getAuthenticator() method without parameters also works only if there is exactly one accepting security provider configured. You can also check the invoking client identity using getReceivedCredentials() method.
Particular Web service endpoints can be configured to perform authorization checks before the invocation of a Web service method. Authorization requirements can be toggled on or off using the WSO2 SOA Enablement Server Server Administration Console or the Providers Manager.
Authorization checks are performed by the WSO2 SOA Enablement Server mediator named AZServiceMediator.
This Web service mediator verifies that the org.idoox.security.server.ReceivedCredentials obtained by getReceivedCredentials() are not null and contain a valid Subject.
This subject is then used to invoke the checkPermissions() method with constructed org.systinet.security.perm.WSInvokePermission on the org.idoox.wasp.WaspSecurity instance.
If no received credentials are found, the only possible way to invoke the service is if the WSO2 SOA Enablement Server is configured to allow access to non-authenticated users.
An important part of securing a Web service is limiting access to it. One way to do this, suitable for some environments, is limiting access based on the client's IP address. WSO2 SOA Enablement Server includes a transport interceptor which can provide such filtering: the class com.idoox.wasp.interceptor.IPFilterInterceptor.
This interceptor acts according to a set of very simple rules. The interceptor has a list of ranges of IP addresses (see the section Specifying ranges for details) and a flag for each range that indicates whether IP addresses falling into this range are to be allowed or blocked. The list is traversed sequentially and the first matching range determines the action. If no range matches the client's IP address, the interceptor's default is used. When the interceptor is created, this default is set to blocking, but it can be changed.
At runtime, this class can be instantiated and configured using its public methods and then added as an interceptor to a service. Example 12 demonstrates this. See Runtime in Publishing Web services for details on runtime service publishing and configuration.
Example 12. Runtime Setup of IPFilterInterceptor
// Copyright 2001-2003 Systinet Corp. All rights reserved. // Use is subject to license terms. package example.security; import com.idoox.wasp.interceptor.IPFilterInterceptor; import example.basics.webservices.HelloServiceImpl; import org.systinet.wasp.Wasp; import org.systinet.wasp.webservice.Interceptors; import org.systinet.wasp.webservice.Registry; import org.systinet.wasp.webservice.ServiceEndpoint; public class IPFiltering { public static void main(String[] args) throws Exception { // booting server System.out.println("Starting server"); Wasp.init("http://localhost:8090/"); try { // adding a sample int storage service System.out.println("Adding the sample service"); ServiceEndpoint serviceEndpoint = Registry.publish("/HelloWorldService/", HelloServiceImpl.class); IPFilterInterceptor interceptor = new IPFilterInterceptor(); // disallowing requests from everywhere interceptor.setAllowedByDefault(false); // allow the addresses 192.168.x.x only interceptor.addRule("192.168.0.0", "255.255.0.0", true); // register interceptor serviceEndpoint.getInterceptors() .insert(interceptor, Interceptors.DIRECTION_IN); System.out.println("Lookup the service"); example.basics.invocation.HelloService svc = (example.basics.invocation.HelloService) Registry.lookup( "http://localhost:8090/HelloWorldService/wsdl", example.basics.invocation.HelloService.class); // call the service, should fail System.out.println("Returned: " + svc.hello("hi")); } catch (Exception e) { e.printStackTrace(); } finally { // shutting the server down System.out.println("Shutting the server down"); Wasp.destroy(); } } }
A service package can be created with IPFilterInterceptor among the service's transport interceptors. Example 13 shows a sample deployment descriptor for such a package.
Example 13. Deployment Setup of IPFilterInterceptor
<?xml version="1.0" encoding="UTF-8"?> <package name="IPFilteredService" targetNamespace="http://systinet.com/examples/security/ipFiltering" version="1.0" xmlns="http://systinet.com/wasp/package/1.1" xmlns:tns="http://systinet.com/examples/security/ipFiltering"> <license>http://systinet.com</license> <service-instance implementation-class="example.basics.webservices.HelloService" name="HelloServiceInstance"/> <processing name="IPFilterProcessing"> <interceptor direction="in" implementation-class="com.idoox.wasp.interceptor.IPFilterInterceptor" name="IPFilterInterceptor"> <configuration> <config allowedByDefault="false"> <!-- the following allows connections from localhost --> <range address="127.0.0.1" allowed="true" netmask="255.255.255.255"/> <!-- the following allows connections from the usual intranet IP address range: 10.x.y.z --> <range address="10.0.0.0" allowed="true" netmask="255.0.0.0"/> </config> </configuration> </interceptor> </processing> <service-endpoint name="FilteredHelloServiceService" path="/HelloService" processing="tns:IPFilterProcessing" service-instance="tns:HelloServiceInstance"/> </package>
This deployment descriptor describes the simple Hello World service (from the example HelloService), allowing connections from the local host and from the A-class network 10.x.x.x (the usual intranet IP address range). The following two commands will deploy this restricted service into your server assuming the following:
Your server is running at http://localhost:6060/
Your current directory is the one in which you compiled the HelloService example
The file ipFilteringDD.xml is in your current directory.
You can then try to run the client and change the descriptor so that it does not accept connections from localhost:
WaspPackager -o hello.jar --dd ipFilteringDD.xml -g -s. deploy --target http://localhost:6060/ -j hello.jar java examples.HelloService.HelloServiceClient
To undeploy the service use the following command:
Undeploy -t http://localhost:6060/ -p http://systinet.com/examples/security/ipFiltering:IPFilteredService
For more information on deployment and deployment descriptors, see Deployment.
An address range is specified in the usual way, by specifying the network address and mask. A given IP address falls into this range if the following is true (the ampersand operator, &, equals a bitwise AND operation):
netaddr & netmask == actual & netmask
Table 8. Sample IP Ranges
Network Address | Network Mask | Range | Remark |
---|---|---|---|
127.0.0.1 | 255.255.255.255 | 127.0.0.1 only | localhost |
10.0.0.0 | 255.0.0.0 | 10.0.0.0 - 10.255.255.255 | range usual for intranets |
192.168.0.0 | 255.255.0.0 | 192.168.0.0 - 192.168.255.255 | other range usual for intranets |
123.45.67.80 | 255.255.255.240 | 123.45.67.80 - 123.45.67.95 | a sample small range |
Apart from only blocking or allowing ranges of IP addresses, this interceptor can be used in combination with specifying multiple service endpoints for one service instance (see Service Instances versus Service Endpoints) to implement more elaborate schemes, for example, allowing all requests from the private network without authentication, but requiring authentication for all other requests.
IP filtering has a two limitations, however:
It is necessary to ensure that IP address spoofing cannot occur, this should be handled by a firewall setup, separating different networks.
This interceptor cannot be used on transports that do not provide client's IP address, for example JMS Topics or email.
The IP filter interceptor can be managed per endpoint from the Web Services Management page of the Administration Console, as described in Message Size, Polymorphism and IP Filtering.