securing webservices Archive

Using RolesAllowed and SecurityRole annotations to secure Webservices on Weblogic

1. Write a JWS that uses the RolesAllowed and SecurityRole annotation

package examples.webservices.security_jws;

import weblogic.jws.WLHttpTransport;
import weblogic.jws.Policies;
import weblogic.jws.Policy;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.soap.SOAPBinding;

import weblogic.jws.security.RolesAllowed;
import weblogic.jws.security.SecurityRole;

@WebService(name="SecureHelloWorldPortType", 
            serviceName="SecureHelloWorldService", 
            targetNamespace="http://www.bea.com")

@SOAPBinding(style=SOAPBinding.Style.DOCUMENT, 
             use=SOAPBinding.Use.LITERAL,
             parameterStyle=SOAPBinding.ParameterStyle.WRAPPED)

@WLHttpTransport(contextPath="SecureHelloWorldService", 
                 serviceUri="SecureHelloWorldService",
		 portName="SecureHelloWorldServicePort")

@RolesAllowed (  { 
    @SecurityRole (role="testrole")
} ) 

public class SecureHelloWorldImpl {

  @WebMethod()
  public String sayHello(String s) {
    return "Hello " + s;  
  }
}

2) While deploying the EAR select custom roles

 

custom roles

3)

Go to myrealm> Realm Roles > Global Roles > Edit Globl Roles and create a new role
testrole and add an existing user to the role

custom roles

 

4) You can invoke the Webservice from SOAP UI by providing the username & password in the request properties.

 

SOAPUI

How to load webservices security policy from classpath

1) Add the following JAVA OPTION to the classpath

-Dweblogic.wsee.policy.LoadFromClassPathEnabled=true

2) Write a simple policy.

Encrypt.xml

 

<?xml version="1.0"?>
<wsp:Policy
  xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
  xmlns:wssp="http://www.bea.com/wls90/security/policy"
  >
  <wssp:Confidentiality>
    <wssp:KeyWrappingAlgorithm URI="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
    <wssp:Target>
      <wssp:EncryptionAlgorithm 
         URI="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
      <wssp:MessageParts 
         Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">
         wsp:Body()
      </wssp:MessageParts>
    </wssp:Target>
    <wssp:KeyInfo/>
  </wssp:Confidentiality>
</wsp:Policy>

3) Write a JWS that uses this Policy

SecureHelloWorldImpl.java

 

package examples.webservices.security_jws;

import weblogic.jws.WLHttpTransport;
import weblogic.jws.Policies;
import weblogic.jws.Policy;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.soap.SOAPBinding;

@WebService(name="SecureHelloWorldPortType", 
            serviceName="SecureHelloWorldService", 
            targetNamespace="http://www.bea.com")

@SOAPBinding(style=SOAPBinding.Style.DOCUMENT, 
             use=SOAPBinding.Use.LITERAL,
             parameterStyle=SOAPBinding.ParameterStyle.WRAPPED)

@WLHttpTransport(contextPath="SecureHelloWorldService", 
                 serviceUri="SecureHelloWorldService",
		 portName="SecureHelloWorldServicePort")

@Policies({
    @Policy(uri="Encrypt.xml",direction=Policy.Direction.inbound)
	})

public class SecureHelloWorldImpl {

  @WebMethod()
  public String sayHello(String s) {
    return "Hello " + s;  
  }
}

4. Build the service.

5. By default policies are placed under the policy folder in WEB-INF

policy-folder

 

6. Create a jar having the policy file

WEB-INF\policies>jar -cvf policy.jar Encrypt.xml

7. Keep policy.jar in the classpath of the server. You can keep it at any location and add the jar to Weblogic Server classpath.
You can also keep it in your domain lib folder.

8. Remove the policies folder from the WEB-INF

9. Deploy the ear.

10. Check the WSDL. The policy should appear there.

wsdl

 

9. Access the application from any client.

10. Your SOAP Request should look like this.

 

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
   <env:Header>
      <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" env:mustUnderstand="1">
         <ns1:EncryptedKey xmlns:ns1="http://www.w3.org/2001/04/xmlenc#" Id="hVJypuPV1a2vyBqJ">
            <ns1:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
            <ns2:KeyInfo xmlns:ns2="http://www.w3.org/2000/09/xmldsig#">
               <wsse:SecurityTokenReference xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="str_B42tel6VDu8at1J1">
                  <ns2:X509Data>
                     <ns2:X509IssuerSerial>
                        <ns2:X509IssuerName>CN=CertGenCAB,OU=FOR TESTING ONLY,O=MyOrganization,L=MyTown,ST=MyState,C=US</ns2:X509IssuerName>
                        <ns2:X509SerialNumber>94119899133620682327187254280110341585</ns2:X509SerialNumber>
                     </ns2:X509IssuerSerial>
                  </ns2:X509Data>
               </wsse:SecurityTokenReference>
            </ns2:KeyInfo>
            <ns1:CipherData>
               <ns1:CipherValue>SIa0pKmZU59OzQGjbYfk/+hbBoVvysjuWrOugwNelkSEW83ohLo/+QZGYqgnNgyo5xbqZp98sS5nPocf5pjuLA==</ns1:CipherValue>
            </ns1:CipherData>
            <ns1:ReferenceList>
               <ns1:DataReference URI="#BrYjknvNmVglOMV2" />
            </ns1:ReferenceList>
         </ns1:EncryptedKey>
      </wsse:Security>
   </env:Header>
   <env:Body>
      <ns1:EncryptedData xmlns:ns1="http://www.w3.org/2001/04/xmlenc#" Id="BrYjknvNmVglOMV2" Type="http://www.w3.org/2001/04/xmlenc#Content" MimeType="text/xml" Encoding="UTF-8">
         <ns1:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
         <ns1:CipherData>
            <ns1:CipherValue>oMNKOEIew22gfa7nx8nUEkYmu0Ksw+lrwxJUJyEfNxjYH0ugkZ8eJv3AAvz0HIv89HKc+ij3Og1o9ncFnFN0DD805ju441DUDBiRleOvy9E=</ns1:CipherValue>
         </ns1:CipherData>
      </ns1:EncryptedData>
   </env:Body>
</env:Envelope>

Securing WebServices using Username / Password mechanism

Security is an important aspect of your application design. When the web services are deployed and accessed, you might like to restrict its accesses to particular set of users/ groups or any users of a particular role. Hence we specify the policies for the application  webservice in this case at the transport level.

WebServices can be secured using the below mechanisms:

Transport-level security secures the connection between the client application and WebLogic Server with Secure Sockets Layer (SSL). SSL provides secure connections by allowing two applications connecting over a network to authenticate the other’s identity and by encrypting the data exchanged between the applications. Authentication allows a server, and optionally a client, to verify the identity of the application on the other end of a network connection. A client certificate (two-way SSL) can be used to authenticate the user.

Encryption makes data transmitted over the network intelligible only to the intended recipient.

Transport-level security includes HTTP BASIC authentication as well as SSL.

Message-Level Security refers to securing some or all of the message content, which relies on the WS-Security specification. WS-Security provides support for encrypting and/or signing part or all of a message. It also provides authentication using token-based credentials. In addition to WS-Security, WebLogic Server also supports the WS-SecureConversation standard to enable a secure session to be established between two trusted parties to facilitate the exchange of multiple messages in a stateful and secure manner.

Access control security answers the question “who can do what?” First you specify the security roles that are allowed to access a Web Service; a security role is a privilege granted to users or groups based on specific conditions. Then, when a client application attempts to invoke a Web Service operation, the client authenticates itself to WebLogic Server, and if the client has the authorization, it is allowed to continue with the invocation. Access control security secures only WebLogic Server resources. That is, if you configureonly access control security, the connection between the client application and WebLogic Server is not secure and the SOAP message is in plain text

 

The below post describes a demonstration of simple username/password-based authentication for webservices.

Pre-requisites :

1: WebService  deployed.

You can refer the below posts to create a sample WebService and a Java stand alone client to access the same.

http://weblogic-wonders.com/weblogic/2011/05/20/webservice-by-bottom-up-approach-using-ant-script/

http://weblogic-wonders.com/weblogic/2011/05/23/creating-stand-alone-webservice-client-from-wsdl/

 

Please follow the steps below:

1. Defining security poilicies:

Define the  policies to the WebService from the console:-

Go to Deployments –> WebService application deployed –> Security –> Policies. From the predicate list select a User / Group/ Role who can access the WebService.

Click save to create the security policy for the WebService.

2: Test the setup:

If you access the WebService without proper credentials, then you would experience the below error.

Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: Access denied to operation sayHelloWorld

at com.sun.xml.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:188)

at com.sun.xml.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:116)

at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:119)

at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:89)

at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:118)

at $Proxy29.sayHelloWorld(Unknown Source)

at com.test.webservice.client.Main.main(Main.java:17)

Caused by: javax.xml.ws.soap.SOAPFaultException: Access denied to operation sayHelloWorld

at weblogic.wsee.jaxws.security.AuthorizationTube.processRequest(AuthorizationTube.java:189)

In the java client, specify the user credentials to access the WebService as below.

Map<String, Object> rc = ((BindingProvider)port).getRequestContext();

rc.put(BindingProvider.USERNAME_PROPERTY, "weblogic");

rc.put(BindingProvider.PASSWORD_PROPERTY, "weblogic");

The JAX-WS BindingProvider class contains username and password properties that we set to specifythe user’s credentials. The underlying web service stub takes care of base 64 encoding these credentials and including them in the HTTP headers of the SOAP request.

A typical java standalone client would look like below.

 

import com.test.webservice.client.*;

import java.util.Map;

import javax.xml.ws.BindingProvider;

public class Main {

public static void main(String[] args) {

com.test.webservice.client.HelloWorldService service = new com.test.webservice.client.HelloWorldService();

com.test.webservice.client.HelloWorldPortType port = service.getHelloWorldPortTypePort();

Map<String, Object> rc = ((BindingProvider)port).getRequestContext();

rc.put(BindingProvider.USERNAME_PROPERTY, "weblogic");

rc.put(BindingProvider.PASSWORD_PROPERTY, "weblogic");

String result=port.sayHelloWorld(" Anandraj ");

System.out.println("********* RESULT from WebService ***********");
System.out.println(result);

System.out.println("********************************************");
}

}

 

Compile and execute the java client, then you would be able to invoke the secured WebService successfully.

You can refer the below link for securing the WebService using the Basic Authentication:

http://weblogic-wonders.com/weblogic/2010/01/04/securing-webservices-using-basic-authentication-on-weblogic-server/

For further reading :

http://download.oracle.com/docs/cd/E12840_01/wls/docs103/webserv_sec/message.html

Regards,

Wonders Team. 🙂