Axis1 webservice security with wss4j

Web Service สามารถถูกเรียกได้จากคนที่รู้จัก WSDL ของเรา เพราะฉะนั้นเราจึงต้องทำการจำกัดสิทธิให้เฉพาะคนที่เราอนุญาตเท่านั้น ซึ่งวิธีการทำ Web Service Security ก็มีหลายวิธี วิธีที่ง่ายที่สุดคือ Username Token

ในตอนที่แล้ว https://magickiat.wordpress.com/2014/05/22/upload-file-with-apache-axis1/ ผมได้สร้าง web service สำหรับ upload file และผมจะทำให้ web service ตัวนี้เรียกได้เฉพาะคนที่มี account ที่ผมระบุเท่านั้น

เครื่องมือที่ใช้


เหมือนตอนที่แล้วเลยครับ แค่เพิ่ม lib ของ http://ws.apache.org/wss4j/index.html แต่มีข้อแม้ว่าต้องใช้ version 1.5.x นะครับ โดยโหลดได้จาก http://archive.apache.org/dist/ws/wss4j/
สรุปว่า lib ที่ผมใช้ต้องเพิ่มดังนี้

  • wss4j-1.5.12.jar
  • xmlsec-1.4.3.jar

คำเตือน: โปรดระวังเรื่อง version ด้วย

ลงมือฝั่ง Server


  1. เพิ่ม lib เข้าไปใน WEB-INF/lib
  2. เปิดไฟล์ server-config.wsdd แล้วไปที่บรรทัด ns1:service name=”Upload”
    service name=Upload
    แล้วเพิ่มคำสั่งนี้ในบรรทัดข้างล่าง

    <ns1:requestFlow>
       <ns1:handler type="java:org.apache.ws.axis.security.WSDoAllReceiver">
        <ns1:parameter name="passwordCallbackClass" value="ws.SecureCallback"/>
        <ns1:parameter name="action" value="UsernameToken"/>
       </ns1:handler>
      </ns1:requestFlow>
    
  3. เพิ่มคลาส Callback เพื่อเป็นการระบุว่า Username ไหนใช้ Password อะไร (ตอนใช้งานจริง password ควรจะเข้ารหัส)
    เพื่อนำไปตรวจสอบกับ Client ที่ส่งเข้ามา

    ซึ่งวิธีที่ง่ายที่สุดก็คือ Fix ไว้ทั้ง Username และ Password แล้วเอาไปให้ Client ที่เราต้องการให้ส่งค่านั้นๆ เข้ามาเลย เพื่อสะดวกในการจัดการ Account

    package ws;
    
    import java.io.IOException;
    
    import javax.security.auth.callback.Callback;
    import javax.security.auth.callback.CallbackHandler;
    import javax.security.auth.callback.UnsupportedCallbackException;
    
    import org.apache.ws.security.WSPasswordCallback;
    
    public class SecureCallback implements CallbackHandler {
    
    	@Override
    	public void handle(Callback[] callbacks) throws IOException,
    			UnsupportedCallbackException {
    		for (int i = 0; i < callbacks.length; i++) {
    
    			if (callbacks[i] instanceof WSPasswordCallback) {
    				WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
    				if ("someuser".equals(pc.getIdentifier())) {
    					pc.setPassword("S3cr3t");
    				}
    			} else {
    				throw new UnsupportedCallbackException(callbacks[i],
    						"Unrecognized Callback");
    			}
    		}
    	}
    }
    
  4. ทำการ Start Server แล้วเรียก URL ของ WSDL หากไม่พบ Erro ถือว่าผ่าน

ลงมือฝั่ง Client


  1. ในตอนนี้หาก Client ทำงานก็จะพบ Error ว่าไม่มี Security header
    ws client error Security header
  2. ให้เพิ่ม lib 2 ตัวที่โหลดมาเข้าไปใน build path
  3. สร้างไฟล์ client_deploy.wsdd ไว้ข้างนอกสุด
    client_deploy.wsdd
    และเพิ่มโค้ดนี้เข้าไป

    <deployment xmlns="http://xml.apache.org/axis/wsdd/"
    	xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
    
    	<transport name="http"
    		pivot="java:org.apache.axis.transport.http.HTTPSender" />
    
    	<globalConfiguration>
    		<requestFlow>
    			<handler type="java:org.apache.ws.axis.security.WSDoAllSender">
    				<parameter name="action" value="UsernameToken" />
    				<parameter name="user" value="someuser" />
    				<parameter name="passwordCallbackClass" value="client.PWCallback" />
    				<parameter name="passwordType" value="PasswordDigest" />
    			</handler>
    		</requestFlow>
    	</globalConfiguration>
    
    </deployment>
    
  4. เพิ่มคลาส Callback เพื่อเป็นการระบุ Username และ Password ที่ได้จาก Server
    package client;
    
    import java.io.IOException;
    
    import javax.security.auth.callback.Callback;
    import javax.security.auth.callback.CallbackHandler;
    import javax.security.auth.callback.UnsupportedCallbackException;
    
    import org.apache.ws.security.WSPasswordCallback;
    
    public class PWCallback implements CallbackHandler {
    
    	@Override
    	public void handle(Callback[] callbacks) throws IOException,
    			UnsupportedCallbackException {
    		for (int i = 0; i < callbacks.length; i++) {
    			if (callbacks[i] instanceof WSPasswordCallback) {
    				WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
    				if ("someuser".equals(pc.getIdentifier())) {
    					pc.setPassword("S3cr3t");
    				}
    			} else {
    				throw new UnsupportedCallbackException(callbacks[i],
    						"Unrecognized Callback");
    			}
    		}
    	}
    }
    
  5. แก้ไข App.java เพื่อ load config ดังนี้
    package client;
    
    import java.io.File;
    import java.io.IOException;
    import java.rmi.RemoteException;
    
    import javax.xml.rpc.ServiceException;
    
    import org.apache.axis.EngineConfiguration;
    import org.apache.axis.configuration.FileProvider;
    import org.apache.commons.io.FileUtils;
    
    import ws.Upload;
    import ws.UploadServiceLocator;
    
    public class App {
    
    	public static void main(String[] args) {
    		try {
    			String uploadFilepath = "E:/workspace/data.txt";
    			
    			EngineConfiguration config = new FileProvider("client_deploy.wsdd");
    			Upload service = new UploadServiceLocator(config).getUpload();
    			
    			boolean status = service.upload(FileUtils.readFileToByteArray(new File(uploadFilepath)));
    			
    			System.out.println("Upload file complete: " + status);
    			
    		} catch (ServiceException e) {
    			e.printStackTrace();
    		} catch (RemoteException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		
    	}
    
    }
    
    
  6. เมื่อรันโปรแกรมก็จะสามารถเรียกใช้งาน web service ได้ตามปกติ
    client calll secure ws
  7. ทดลองเปลี่ยน password ของ client ที่ไม่ตรงกับ Server ก็จะพบกับข้อความว่าไม่ได้รับอนุญาตให้ใช้งาน
    client call secure ws with wrong password
Advertisements

2 thoughts on “Axis1 webservice security with wss4j

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s