1 /* zxidwspdemo.java - Demonstrate server side of handling a web service call (middle) 2 * Copyright (c) 2012-2016 Synergetics (sampo@synergetics.be), All Rights Reserved. 3 * Copyright (c) 2010-2011 Sampo Kellomaki (sampo@iki.fi), All Rights Reserved. 4 * Copyright (c) 2009 Symlabs (symlabs@symlabs.com), All Rights Reserved. 5 * Author: Sampo Kellomaki (sampo@iki.fi) 6 * This is confidential unpublished proprietary source code of the author. 7 * NO WARRANTY, not even implied warranties. Contains trade secrets. 8 * Distribution prohibited unless authorized in writing. 9 * Licensed under Apache License 2.0, see file COPYING. 10 * $Id: zxidappdemo.java,v 1.3 2009-11-20 20:27:13 sampo Exp $ 11 * 16.10.2009, created --Sampo 12 * 16.2.2010, fixed virtual hosting --Sampo 13 * 7.2.2012, new virtual hosting with <init-param> supplied config --Sampo 14 * 19.2.2016, improved visualization of the Az steps --Sampo 15 * 16 * See also: zxid-java.pd, zxidappdemo.java for client side 17 * 18 * Discovery registration: 19 * ./zxcot -e http://sp.tas3.pt:8080/zxidservlet/wspdemo 'TAS3 WSP Demo' http://sp.tas3.pt:8080/zxidservlet/wspdemo?o=B urn:x-foobar | ./zxcot -d -b /var/zxid/idpdimd 20 * touch /var/zxid/idpuid/.all/.bs/urn_x-foobar,l9O3xlWWi9kLZm-yQYRytpf0lqw 21 */ 22 23 import zxidjava.*; // Pull in the zxidjni.az() API 24 import java.io.*; 25 import javax.servlet.*; 26 import javax.servlet.http.*; 27 28 public class zxidwspdemo extends HttpServlet { 29 static zxidjava.zxid_conf cf; 30 static { System.loadLibrary("zxidjni"); } 31 init_zxid_vhost(HttpServletRequest req)32 public void init_zxid_vhost(HttpServletRequest req) 33 throws ServletException 34 { 35 // CONFIG: You must have created /var/zxid directory hierarchy. See `make dir' 36 // CONFIG: To set config string, edit web.xml (hope you know where it is) and 37 // add to your servlets sections like 38 // <servlet> 39 // <servlet-name>zxidsrvlet</servlet-name><servlet-class>zxidsrvlet</servlet-class> 40 // <init-param> 41 // <param-name>ZXIDConf</param-name><param-value>PATH=/var/zxid/</param-value> 42 // </init-param> 43 // </servlet> 44 // CONFIG: You must edit the URL to match your domain name and port, usually you 45 // CONFIG: would create and edit /var/zxid/zxid.conf and override the URL there. 46 // CONFIG: However, this program sets the URL dynamically, see calls to zxidjni.url_set() 47 if (cf == null) { 48 String conf = getServletConfig().getInitParameter("ZXIDConf"); 49 cf = zxidjni.new_conf_to_cf(conf); 50 zxidjni.set_opt(cf, 1, 1); 51 } 52 String scheme = req.getScheme(); 53 String host_hdr = req.getHeader("HOST"); 54 String fullURL = req.getRequestURI(); 55 String url = scheme + "://" + host_hdr + fullURL; 56 System.err.print("url("+url+")\n"); // URL=http://sp.tas3.pt:8080/zxidservlet/wspdemo 57 zxidjni.url_set(cf, url); // Virtual host support 58 } 59 60 // Only reason why a pure WSP would handle GET is supporting WKL metadata 61 // exchange (o=B). However, a hybrid frontend SP plus WSP would handle its SSO here. 62 doGet(HttpServletRequest req, HttpServletResponse res)63 public void doGet(HttpServletRequest req, HttpServletResponse res) 64 throws ServletException, IOException 65 { 66 System.err.print("Start GET...\n"); 67 init_zxid_vhost(req); 68 String qs = req.getQueryString(); 69 if (qs != null && (qs.equals("o=B") || qs.equals("o=d"))) { // Metadata check 70 String ret = zxidjni.simple_cf(cf, -1, qs, null, 0x3d54); // QS response requested 71 System.err.print(ret); 72 switch (ret.charAt(0)) { 73 case 'L': /* Redirect: ret == "LOCATION: urlCRLF2" */ 74 res.sendRedirect(ret.substring(10, ret.length() - 4)); 75 return; 76 case '<': 77 switch (ret.charAt(1)) { 78 case 's': case 'm': res.setContentType("text/xml"); break; /* <m20: metadata ... */ 79 default: res.setContentType("text/html"); break; 80 } 81 res.setContentLength(ret.length()); 82 res.getOutputStream().print(ret); 83 break; 84 default: 85 System.err.print("Unhandled zxid_simple() response("+ret+").\n"); 86 } 87 return; 88 } 89 90 res.setContentType("text/html"); 91 res.getOutputStream().print("<title>ZXID Demo WSP</title><body><h1>ZXID Demo WSP does not offer web GUI (" + req.getRequestURI() + ")</H1>\n<pre>"+qs+"</pre>"); 92 } 93 94 // Handle a SOAP call, which is always a POST 95 doPost(HttpServletRequest req, HttpServletResponse res)96 public void doPost(HttpServletRequest req, HttpServletResponse res) 97 throws ServletException, IOException 98 { 99 String ret; 100 System.err.print("\n============ WSP Start SOAP POST ============\n"); 101 init_zxid_vhost(req); 102 zxidjava.zxid_ses ses = zxidjni.alloc_ses(cf); 103 104 // Java / Servlet complicated way of reading in the POST input 105 106 String buf; 107 int len = req.getContentLength(); 108 byte[] b = new byte[len]; 109 int here, got; 110 for (here = 0; here < len; here += got) 111 got = req.getInputStream().read(b, here, len - here); 112 buf = new String(b, 0, len); 113 114 // Check the input for correct ID-WSF compliance 115 116 System.err.print("Validating buf("+buf+")\n"); 117 String nid = zxidjni.wsp_validate(cf, ses, "Resource=demo", buf); 118 if (nid == null) { 119 System.err.print("Validate fail buf("+buf+")\n"); 120 ret = zxidjni.wsp_decorate(cf, ses, "Resource=demo:fail", 121 "<barfoo>" 122 + "<lu:Status code=\"Fail\" comment=\"INVALID. Token replay?\"></lu:Status>" + 123 "</barfoo>"); 124 res.getOutputStream().print(ret); 125 System.err.print("^^^^^^^^^^^^^ WSP inval ("+ret.length()+" chars output) ^^^^^^^^^^^^^\n\n"); 126 return; 127 } 128 String ldif = zxidjni.ses_to_ldif(cf, ses); 129 System.err.print("\n===== Doing work for user nid("+nid+").\nAttribute dump: "+ldif+"\n"); 130 ldif = "<img src=\"green-check-20x20.png\">WSP2 Authorized by PDP (B).<br>\n"+ldif+"<img src=\"green-check-20x20.png\">WSP3 Authorized by PDP (B).<br>\n"; 131 132 // Perform a application dependent authorization step and ship the response 133 134 if (zxidjni.az_cf_ses(cf, "Action=Call", ses) == null) { 135 System.err.print("Explicit Az fail\n"); 136 ret = zxidjni.wsp_decorate(cf, ses, "Resource=demo:fail", 137 "<barfoo>" 138 + "<lu:Status code=\"Fail\" comment=\"Denied\"></lu:Status>" 139 + "<data>Denied: nid="+nid+"</data>" + 140 "</barfoo>"); 141 } else { 142 String recurse = ""; 143 if (buf.indexOf("STOP") == -1) { 144 // "http://sp.tas3.pt:8080/zxidservlet/wspleaf?o=B" 145 ldif = "<img src=\"green-check-20x20.png\">WSP2 Authorized by PDP (B).<br>\n"+ldif+"<img src=\"green-check-20x20.png\">WSP3 Authorized by PDP (B).<br>\n"; 146 recurse = zxidjni.call(cf, ses, "x-recurs", null, null, "Resource=leaf", "<recursing>STOP</recursing>"); 147 //recurse = zxidjni.call(cf, ses, "urn:x-foobar", "http://sp.tas3.pt:8080/zxidservlet/wspdemo?o=B", null, null, "<recursing>STOP</recursing>"); 148 System.err.print("Recursive out("+recurse+")\n"); 149 recurse = zxidjni.extract_body(cf, recurse); 150 recurse += "<img src=\"green-check-20x20.png\">WSC4 Authorized by PDP (B).<br>\n"+ldif+"<img src=\"green-check-20x20.png\">WSP3 Authorized by PDP (B).<br>\n"; 151 } else { 152 System.err.print("Recursive STOP\n"); 153 } 154 155 ldif = "<img src=\"green-check-20x20.png\">WSP2 Authorized by PDP (B).<br>\n"+ldif+"<img src=\"green-check-20x20.png\">WSP3 Authorized by PDP (B).<br>\n"; 156 157 ret = zxidjni.wsp_decorate(cf, ses, "Resource=demo", 158 "<barfoo>" 159 + "<lu:Status code=\"OK\" comment=\"Permit\"></lu:Status>" 160 + "<data>nid="+nid+"\n"+ldif+"\n\nRECURSE OUT:\n"+recurse+"\n</data>" + 161 "</barfoo>"); 162 } 163 164 res.getOutputStream().print(ret); 165 System.err.print("^^^^^^^^^^^^^ WSP Done ("+ret.length()+" chars output) ^^^^^^^^^^^^^\n\n"); 166 } 167 } 168 169 /* EOF */ 170 //String proto = req.getProtocol(); 171 //String servername = req.getServerName(); 172 //int serverport = req.getServerPort(); 173 //String qs = req.getQueryString(); 174 //System.err.print("proto("+proto+")\n"); 175 //System.err.print("scheme("+scheme+")\n"); 176 //System.err.print("servername("+servername+")\n"); 177 //System.err.print("serverport("+serverport+")\n"); 178 //System.err.print("host_hdr("+host_hdr+")\n"); 179 //System.err.print("fullURL("+fullURL+")\n"); 180 //System.err.print("qs("+qs+")\n"); 181 //String url = scheme + "://" + servername 182 // + (serverport != 80 && serverport != 443 ? ":"+serverport : "") 183 // + fullURL; 184