Coverage Report - org.kuali.student.security.trust.service.SecurityTokenServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
SecurityTokenServiceImpl
48%
56/115
41%
20/48
4.455
 
 1  
 package org.kuali.student.security.trust.service;
 2  
 
 3  
 import java.io.BufferedReader;
 4  
 import java.io.InputStreamReader;
 5  
 import java.io.StringWriter;
 6  
 import java.io.UnsupportedEncodingException;
 7  
 import java.net.HttpURLConnection;
 8  
 import java.net.URL;
 9  
 import java.net.URLEncoder;
 10  
 import java.util.HashMap;
 11  
 import java.util.List;
 12  
 import java.util.Map;
 13  
 
 14  
 import javax.jws.WebService;
 15  
 import javax.xml.bind.JAXBElement;
 16  
 import javax.xml.parsers.DocumentBuilder;
 17  
 import javax.xml.parsers.DocumentBuilderFactory;
 18  
 import javax.xml.transform.Transformer;
 19  
 import javax.xml.transform.TransformerFactory;
 20  
 import javax.xml.transform.dom.DOMSource;
 21  
 import javax.xml.transform.stream.StreamResult;
 22  
 
 23  
 import org.jasig.cas.client.util.CommonUtils;
 24  
 import org.jasig.cas.client.util.XmlUtils;
 25  
 import org.kuali.student.security.exceptions.KSSecurityException;
 26  
 import org.kuali.student.security.trust.dto.RequestSecurityTokenResponseCollectionType;
 27  
 import org.kuali.student.security.trust.dto.RequestSecurityTokenResponseType;
 28  
 import org.kuali.student.security.trust.dto.RequestSecurityTokenType;
 29  
 import org.kuali.student.security.util.SamlUtils;
 30  
 import org.opensaml.SAMLAssertion;
 31  
 import org.w3c.dom.Document;
 32  
 import org.w3c.dom.Element;
 33  
 import org.w3c.dom.Node;
 34  
 
 35  
 /**
 36  
  * This class was generated by Apache CXF 2.2.8
 37  
  * Thu Jun 03 14:08:34 EDT 2010
 38  
  * Generated source version: 2.2.8
 39  
  * 
 40  
  */
 41  
  
 42  
 @WebService(endpointInterface = "org.kuali.student.security.trust.service.SecurityTokenService", serviceName = "SecurityTokenService", 
 43  
             portName = "SecurityTokenService", targetNamespace = "http://schemas.xmlsoap.org/ws/2005/02/trust/wsdl")
 44  2
 public class SecurityTokenServiceImpl implements SecurityTokenService {
 45  
 
 46  
     public static final String WST_NS_05_02 = "http://schemas.xmlsoap.org/ws/2005/02/trust";
 47  
     public static final String SAML_11_NS = "urn:oasis:names:tc:SAML:1.0:assertion";
 48  
     
 49  
     
 50  
     private String casServerUrl;
 51  
     private String samlIssuerForUser;
 52  
     private String proxyCallBackUrl;
 53  
     
 54  
     public RequestSecurityTokenResponseCollectionType requestSecurityToken2(RequestSecurityTokenType request) throws KSSecurityException
 55  
     {
 56  1
         return null;
 57  
     }
 58  
 
 59  
     public RequestSecurityTokenResponseType requestSecurityToken(RequestSecurityTokenType request) throws KSSecurityException
 60  
     {
 61  
         // Parse the request
 62  1
         String context = request.getContext();
 63  1
         List<Object> objects = request.getAny();
 64  
         
 65  1
         String tokenTypeUri = null;
 66  1
         String requestTypeUri = null;
 67  1
         String proxyTicketId = null;
 68  1
         String proxyTargetService = null;
 69  
         
 70  1
         for(Object o : objects){
 71  
             // if its being accessed as a SOAP service with JAXB.
 72  4
             if(o instanceof JAXBElement){
 73  0
                 JAXBElement<?> e = (JAXBElement<?>)o;
 74  0
                 if( e.getName().getLocalPart().equalsIgnoreCase("TokenType")){
 75  0
                     tokenTypeUri = (String)e.getValue();
 76  
                 }
 77  0
                 else if(e.getName().getLocalPart().equalsIgnoreCase("RequestType")) {
 78  0
                     requestTypeUri = (String)e.getValue();
 79  
                 }
 80  0
                 else if(e.getName().getLocalPart().equalsIgnoreCase("CasProxyTicket")) {
 81  0
                     proxyTicketId = (String)e.getValue();
 82  
                 }
 83  0
                 else if(e.getName().getLocalPart().equalsIgnoreCase("CasProxyTargetService")) {
 84  0
                     proxyTargetService = (String)e.getValue();
 85  
                 }
 86  
             
 87  
             // if its being accessed with a client impl, no SOAP.
 88  0
             } else if(o instanceof Element){
 89  4
                 Element e = (Element)o;
 90  4
                 if( e.getLocalName().equalsIgnoreCase("TokenType")){
 91  1
                     tokenTypeUri = e.getTextContent();
 92  
                 }
 93  3
                 else if(e.getLocalName().equalsIgnoreCase("RequestType")) {
 94  1
                     requestTypeUri = e.getTextContent();
 95  
                 }
 96  2
                 else if(e.getLocalName().equalsIgnoreCase("CasProxyTicket")) {
 97  1
                     proxyTicketId = e.getTextContent();
 98  
                 }
 99  1
                 else if(e.getLocalName().equalsIgnoreCase("CasProxyTargetService")) {
 100  1
                     proxyTargetService = e.getTextContent();
 101  
                 }
 102  4
             }
 103  
         }
 104  
         
 105  
         
 106  
         // Create the Response
 107  1
         RequestSecurityTokenResponseType rstr = new RequestSecurityTokenResponseType();
 108  
         
 109  1
         if(requestTypeUri == null){ 
 110  0
             throw new KSSecurityException("The element RequestType is required");
 111  
         }
 112  1
         if(proxyTicketId == null || proxyTargetService == null){
 113  0
             throw new KSSecurityException("The elements CasProxyTicket and CasProxyTargetService are required");
 114  
         }
 115  
         
 116  
         //This optional URI specifies the identifier from the original request.
 117  
        // That is, if a context URI is specified on a RST, then it MUST be echoed on the corresponding RSTRs.
 118  1
         if(context != null){
 119  1
             rstr.setContext(context);
 120  
         }
 121  
         
 122  1
         if(tokenTypeUri == null){
 123  
             //default to SAML
 124  0
             tokenTypeUri = SAML_11_NS;
 125  
         }
 126  
        
 127  
         // We are just handling request for tokens of type SAML and for new token issuing, so this is just one BAD mother IF.
 128  1
         if(tokenTypeUri.equals(SAML_11_NS) && requestTypeUri.endsWith("/Issue") ){
 129  
             // create the TokenType and RequestedSecurityToken Elements
 130  1
             Element tokenType = null;
 131  1
             Element requestedSecurityToken = null;
 132  1
             Document signedSAMLDoc = null;
 133  
             try{
 134  
                 
 135  1
                 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 136  
         
 137  
                 //XML Signature needs to be namespace aware -- not sure if I need this here
 138  1
                 dbf.setNamespaceAware(true);
 139  
         
 140  1
                 DocumentBuilder db = dbf.newDocumentBuilder();
 141  1
                 Document doc = db.newDocument();
 142  
         
 143  1
                 tokenType = doc.createElementNS(WST_NS_05_02, "TokenType");
 144  1
                 tokenType.setTextContent(tokenTypeUri);
 145  
                 
 146  1
                 requestedSecurityToken = doc.createElementNS(WST_NS_05_02, "RequestedSecurityToken");
 147  
                 
 148  1
                 String testProperty = System.getProperty("ks.test.securityTokenService.useCas", "true");
 149  
                 
 150  1
                 if(Boolean.valueOf(testProperty)){
 151  0
                     signedSAMLDoc = validateCasProxyTicket(proxyTicketId, proxyTargetService);
 152  
                 } else {
 153  
                     // Create TEST SAML
 154  1
                     signedSAMLDoc = getSamlPrincipal("WS Trust Service is in test mode");
 155  
                 }
 156  1
                 Node signedSAMLAssertion = signedSAMLDoc.getDocumentElement();
 157  1
                 requestedSecurityToken.appendChild(doc.importNode(signedSAMLAssertion, true));
 158  
                 
 159  0
             } catch(Exception e){
 160  0
                 throw new KSSecurityException(e);
 161  1
             }
 162  1
             rstr.getAny().add(tokenType);
 163  1
             rstr.getAny().add(requestedSecurityToken);
 164  
         }
 165  
         
 166  1
         return rstr;
 167  
     }
 168  
 
 169  
     private Document validateCasProxyTicket(String proxyTicketId, String proxyTargetService) throws KSSecurityException{
 170  
         
 171  0
         String url = constructUrl(proxyTicketId, proxyTargetService);
 172  0
         HttpURLConnection conn = null;
 173  
         
 174  
         try {
 175  0
             URL constructedUrl = new URL(url);
 176  0
             conn = (HttpURLConnection) constructedUrl.openConnection();
 177  
 
 178  0
             BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
 179  
 
 180  
             String line;
 181  0
             StringBuffer stringBuffer = new StringBuffer(255);
 182  
             String response;
 183  
 
 184  0
             while ((line = in.readLine()) != null) {
 185  0
                 stringBuffer.append(line);
 186  
             }
 187  
             
 188  0
             response = stringBuffer.toString();
 189  0
             String error = XmlUtils.getTextForElement(response, "authenticationFailure");
 190  
 
 191  0
             if (CommonUtils.isNotEmpty(error)) {
 192  
                 //return error;
 193  0
                 throw new KSSecurityException(error);
 194  
             }
 195  
 
 196  0
             String user = XmlUtils.getTextForElement(response, "user");
 197  0
             String pgt  = XmlUtils.getTextForElement(response, "proxyGrantingTicket");
 198  0
             String proxies = XmlUtils.getTextForElement(response, "proxies");
 199  
             
 200  0
             Map<String,String> samlProperties = new HashMap<String,String>();
 201  0
             samlProperties.put("user", user.trim());
 202  0
             samlProperties.put("proxyGrantingTicket", pgt.trim());
 203  0
             samlProperties.put("proxies", proxies.trim());
 204  0
             samlProperties.put("samlIssuerForUser", samlIssuerForUser.trim());
 205  
             
 206  0
             SamlUtils.setSamlProperties(samlProperties);
 207  0
             SAMLAssertion samlAssertion = SamlUtils.createAssertion();
 208  
             
 209  0
             Document signedSAML = SamlUtils.signAssertion(samlAssertion);
 210  0
             return signedSAML;
 211  
             
 212  
             // transform the saml DOM into a writer, and return as a string response
 213  
             /*DOMSource domSource = new DOMSource(signedSAML);
 214  
             StringWriter writer = new StringWriter();
 215  
             StreamResult result = new StreamResult(writer);
 216  
             
 217  
             TransformerFactory tf = TransformerFactory.newInstance();
 218  
             Transformer transformer;
 219  
             
 220  
             transformer = tf.newTransformer();
 221  
             transformer.transform(domSource, result);
 222  
             
 223  
             writer.flush();
 224  
             
 225  
             return writer.toString();*/
 226  
             
 227  0
         } catch (final Exception e) {
 228  0
             throw new KSSecurityException(e);
 229  
         } finally {
 230  0
             if (conn != null) {
 231  0
                 conn.disconnect();
 232  
             }
 233  
         }
 234  
     }
 235  
     
 236  
     private String constructUrl(String proxyTicketId, String proxyTargetService) throws KSSecurityException{
 237  
         try {
 238  0
             return this.casServerUrl + (this.casServerUrl.endsWith("/") ? "" : "/") + "proxyValidate" + "?ticket=" 
 239  
             + proxyTicketId + "&service=" + URLEncoder.encode(proxyTargetService, "UTF-8") 
 240  
             + "&pgtUrl=" + URLEncoder.encode(proxyCallBackUrl, "UTF-8");
 241  0
         } catch (UnsupportedEncodingException e) {
 242  0
             throw new KSSecurityException(e);
 243  
         }
 244  
     }
 245  
     
 246  
     private Document getSamlPrincipal(String principal) throws KSSecurityException{
 247  
         try {      
 248  1
             Map<String,String> samlProperties = new HashMap<String,String>();
 249  1
             samlProperties.put("user", principal);
 250  1
             samlProperties.put("proxyGrantingTicket", "");
 251  1
             samlProperties.put("proxies", "");
 252  1
             if(samlIssuerForUser == null){
 253  1
                 samlProperties.put("samlIssuerForUser", "org.kuali.student.trust.sts");
 254  
             }else{
 255  0
                 samlProperties.put("samlIssuerForUser", samlIssuerForUser.trim());
 256  
             }
 257  
             
 258  1
             SamlUtils.setSamlProperties(samlProperties);
 259  1
             SAMLAssertion samlAssertion = SamlUtils.createAssertion();
 260  
             
 261  1
             Document signedSAML = SamlUtils.signAssertion(samlAssertion);
 262  
             
 263  1
             return signedSAML;
 264  
             
 265  0
         } catch (final Exception e) {
 266  0
             throw new KSSecurityException(e);
 267  
         } 
 268  
 
 269  
     }
 270  
 
 271  
     public String getCasServerUrl() {
 272  0
         return casServerUrl;
 273  
     }
 274  
 
 275  
     public void setCasServerUrl(String casServerUrl) {
 276  0
         this.casServerUrl = casServerUrl;
 277  0
     }
 278  
 
 279  
     public String getSamlIssuerForUser() {
 280  0
         return samlIssuerForUser;
 281  
     }
 282  
 
 283  
     public void setSamlIssuerForUser(String samlIssuerForUser) {
 284  0
         this.samlIssuerForUser = samlIssuerForUser;
 285  0
     }
 286  
 
 287  
     public String getProxyCallBackUrl() {
 288  0
         return proxyCallBackUrl;
 289  
     }
 290  
 
 291  
     public void setProxyCallBackUrl(String proxyCallBackUrl) {
 292  0
         this.proxyCallBackUrl = proxyCallBackUrl;
 293  0
     }
 294  
 }