JAX – WS – 16 – Authentication
Merhaba arkadaslar
Bu bolumde JAX-WS Authentication konusunu inceleyecegiz.
Oncelikle , yeni bir proje olusturalim.
(Ornek projeyi bolum sonunda belirttigim , Github hesabim uzerinden ulasabilirsiniz
proje : injavawetrust.jaxws.authentication)
Model
package ws.model; import java.util.Date; public class Order { private String orderId; private Date orderDate; private double amount; public Order() { super(); } public Order(String orderId, Date orderDate, double amount) { super(); this.orderId = orderId; this.orderDate = orderDate; this.amount = amount; } //getters and setters ... }
In Memory Sample Data
Simdi de inmemory olarak kullanabilecegimiz sample data’yi olusturalim.
package ws.inmemory; import java.util.Date; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import ws.model.Order; public class MemoryData { public static List<Order> orders = new ArrayList<>(); static { Calendar calendar = Calendar.getInstance(); calendar.set(2017, 11, 1, 20, 25, 53); Date date1 = calendar.getTime(); calendar.set(2017, 11, 9, 21, 30, 20); Date date2 = calendar.getTime(); calendar.set(2017, 11, 10, 22, 10, 50); Date date3 = calendar.getTime(); Order order1 = new Order("Order-100", date1, 10); Order order2 = new Order("Order-200", date2, 20); Order order3 = new Order("Order-300", date3, 30); orders.add(order1); orders.add(order2); orders.add(order3); } public static Order getOrder(String id) { return MemoryData.orders.stream().filter(p -> id.equals(p.getOrderId())).findFirst().get(); } public static Order[] getOrders() { return orders.toArray(new Order[orders.size()]); } }
getOrder metodunda id degerine gore ilgili Order donuyoruz , getOrders metodunda ise List-> array donusumu yapiyoruz.
(List , ArrayList donus tipindeki metotlar JAX-WS te problem cikartmaktadir)
Web Service
OrderWS.java
OrderWS interface te @WebService , @WebMethod , @WebParam annotation larini kullanarak Web Service tanimlarini yapiyoruz.
2 tane metodumuz olacak ve bu metotlar OrderWSException firlatmaktadir. Asagida bu sinifi da olusturacagiz.
package ws.service; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; import javax.jws.soap.SOAPBinding.Style; import ws.exception.OrderWSException; import ws.model.Order; @WebService @SOAPBinding(style = Style.RPC) public interface OrderWS { @WebMethod public Order getOrder(@WebParam(name = "id") String id) throws OrderWSException; @WebMethod public Order[] getOrders() throws OrderWSException; }
OrderWSImpl.java
@Resource annotation’ini kullaniyoruz. Boylece injection gerceklesecek.
WebServiceContext tipindeki degiskeni authenticate metoduna gonderiyoruz. Asagida AuthenticateService sinifini da olusturacagiz.
package ws.service; import javax.annotation.Resource; import javax.jws.WebService; import javax.xml.ws.WebServiceContext; import ws.exception.OrderWSException; import ws.inmemory.MemoryData; import ws.model.Order; @WebService(endpointInterface = "ws.service.OrderWS") public class OrderWSImpl implements OrderWS { @Resource private WebServiceContext wsContext; @Override public Order getOrder(String id) throws OrderWSException { AuthenticateService.authenticate(wsContext); return MemoryData.getOrder(id); } @Override public Order[] getOrders() throws OrderWSException { AuthenticateService.authenticate(wsContext); return MemoryData.getOrdersAsArray(); } }
Exception
OrderWSException sinifini olusturalim …
package ws.exception; public class OrderWSException extends Exception { private String errorCode; private String errorDesc; public OrderWSException(String errorCode) { super(); this.errorCode = errorCode; } public OrderWSException(String errorCode, String errorDesc) { super(); this.errorCode = errorCode; this.errorDesc = errorDesc; } //getters and setters // }
Authenticate Service
AuthenticateService.java
Simdi de AuthenticateService sinifimizi yazalim.
WebServiceContext#getMessageContext metodu ile MessageContext objesini elde ediyoruz. ( MessageContext interface’i Map interface’ini kalitmaktadir)
MessageContext.HTTP_REQUEST_HEADERS degerini key olarak kullaniyoruz geriye yine header’lari tutan Map donmektedir.
Sonrasinda bu Map uzerinden username ve password key bilgilerini kullanarak List objelerini elde ediyoruz.
Her sey yolundaysa (ornek amacli test ettigimiz admin ve 12345 bilgileriyle gelen bilgiler uyusuyorsa) true donecektir , aksi durumda yeni bir exception firlatiyoruz.
package ws.service; import java.util.List; import java.util.Map; import javax.xml.ws.WebServiceContext; import javax.xml.ws.handler.MessageContext; import ws.exception.OrderWSException; public class AuthenticateService { private static final String allowedUser = "admin"; private static final String allowedPassword = "12345"; @SuppressWarnings("unchecked") public static boolean authenticate(WebServiceContext wsContext) throws OrderWSException { MessageContext messageContext = wsContext.getMessageContext(); Map<String, Object> httpHeaders = (Map<String, Object>) messageContext.get(MessageContext.HTTP_REQUEST_HEADERS); List<String> userList = (List<String>) httpHeaders.get("username"); List<String> passList = (List<String>) httpHeaders.get("password"); String username = null; String password = null; if (userList != null && passList != null) { username = userList.get(0); password = passList.get(0); } if (!allowedUser.equals(username) || !allowedPassword.equals(password)) { throw new OrderWSException("Error-1001", "username or password invalid."); } return true; } }
Client & Run Application
Client sinifimizi yazalim..
SOAP Messagelarini Trace etmek icin System.property ile ilgili property ekleyelim.
Su bolumde incelemistik..
http://www.injavawetrust.com/jax-ws-05-trace-soap-messages/
Sonrasinda BindingProvider#getRequestContext metodu ile Map<String, Object> objesi elde ettik.
Ilgili header’lari map’e ekliyoruz (username ve password) , dikkat edecek olursak bu key’ler AuthenticateService’teki degerler ile ayni. Bunlarin eslesmesi/ayni olmasi gerekli !
Sonrasinda MessageContext.HTTP_REQUEST_HEADER key bilgisi ile Map’e header map’ini ekliyoruz.
Client.java
package ws.client; import java.net.MalformedURLException; import java.net.URL; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.naming.AuthenticationException; import javax.xml.namespace.QName; import javax.xml.ws.Service; import javax.xml.ws.handler.MessageContext; import javax.xml.ws.BindingProvider; import ws.exception.OrderWSException; import ws.model.Order; import ws.service.OrderWS; //1- run the WebServicePublisher //2- test Client.java public class Client { private static String WEB_SERVICE_WSDL_URL = "http://localhost:8888/injavawetrust/orderws?wsdl"; public static void main(String[] args) throws MalformedURLException, AuthenticationException, OrderWSException { //Trace SOAP message System.setProperty("com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump", "true"); URL url = new URL(WEB_SERVICE_WSDL_URL); QName qname = new QName("http://service.ws/", "OrderWSImplService"); Service service = Service.create(url, qname); OrderWS orderWS = service.getPort(OrderWS.class); Map<String, Object> requestContext = ((BindingProvider) orderWS).getRequestContext(); Map<String, List<String>> requestHeaders = new HashMap<String, List<String>>(); // requestHeaders.put("username", Arrays.asList("admin")); requestHeaders.put("password", Arrays.asList("12345")); requestContext.put(MessageContext.HTTP_REQUEST_HEADERS, requestHeaders); System.out.println("Order100"); Order order100 = orderWS.getOrder("Order-100"); System.out.println(order100); System.out.println("All Orders ..."); for (Order order : orderWS.getOrders()) { System.out.println(order); } } }
Ornegi calistirdigimizda …
Order100 ---[HTTP request - http://localhost:8888/injavawetrust/orderws]--- Accept: text/xml, multipart/related Content-Type: text/xml; charset=utf-8 password: 12345 SOAPAction: "http://service.ws/OrderWS/getOrderRequest" User-Agent: JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e username: admin <?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:getOrder xmlns:ns2="http://service.ws/"><id>Order-100</id></ns2:getOrder></S:Body></S:Envelope>-------------------- ---[HTTP response - http://localhost:8888/injavawetrust/orderws - 200]--- null: HTTP/1.1 200 OK Content-type: text/xml; charset=utf-8 Date: Sun, 10 Dec 2017 14:10:09 GMT Transfer-encoding: chunked <?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:getOrderResponse xmlns:ns2="http://service.ws/"><return><amount>10.0</amount><orderDate>2017-12-01T20:25:53.004+03:00</orderDate><orderId>Order-100</orderId></return></ns2:getOrderResponse></S:Body></S:Envelope>-------------------- Order [orderId=Order-100, orderDate=Fri Dec 01 20:25:53 EET 2017, amount=10.0] All Orders ... ---[HTTP request - http://localhost:8888/injavawetrust/orderws]--- Accept: text/xml, multipart/related Content-Type: text/xml; charset=utf-8 password: 12345 SOAPAction: "http://service.ws/OrderWS/getOrdersRequest" User-Agent: JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e username: admin <?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:getOrders xmlns:ns2="http://service.ws/"></ns2:getOrders></S:Body></S:Envelope>-------------------- ---[HTTP response - http://localhost:8888/injavawetrust/orderws - 200]--- null: HTTP/1.1 200 OK Content-type: text/xml; charset=utf-8 Date: Sun, 10 Dec 2017 14:10:09 GMT Transfer-encoding: chunked <?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:getOrdersResponse xmlns:ns2="http://service.ws/"><return><item><amount>10.0</amount><orderDate>2017-12-01T20:25:53.004+03:00</orderDate><orderId>Order-100</orderId></item><item><amount>20.0</amount><orderDate>2017-12-09T21:30:20.004+03:00</orderDate><orderId>Order-200</orderId></item><item><amount>30.0</amount><orderDate>2017-12-10T22:10:50.004+03:00</orderDate><orderId>Order-300</orderId></item></return></ns2:getOrdersResponse></S:Body></S:Envelope>-------------------- Order [orderId=Order-100, orderDate=Fri Dec 01 20:25:53 EET 2017, amount=10.0] Order [orderId=Order-200, orderDate=Sat Dec 09 21:30:20 EET 2017, amount=20.0] Order [orderId=Order-300, orderDate=Sun Dec 10 22:10:50 EET 2017, amount=30.0]
Dikkat edecek olursak username ve password bilgisi header olarak gitmektedir.
password olarak 12345 yerine 123456 gonderirsek…
---[HTTP response - http://localhost:8888/injavawetrust/orderws - 500]--- null: HTTP/1.1 500 Internal Server Error Content-type: text/xml; charset=utf-8 Date: Sun, 10 Dec 2017 14:13:12 GMT Transfer-encoding: chunked <?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope" xmlns=""><faultcode>S:Server</faultcode><faultstring>ws.exception.OrderWSException</faultstring><detail><ns2:OrderWSException xmlns:ns2="http://service.ws/"><errorCode>Error-1001</errorCode><errorDesc>username or password invalid.</errorDesc></ns2:OrderWSException></detail></S:Fault></S:Body></S:Envelope>-------------------- Exception in thread "main" ws.exception.OrderWSException at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ...
Leave a Reply