View Javadoc

1   /**
2    * Copyright 2010 The Kuali Foundation Licensed under the
3    * Educational Community License, Version 2.0 (the "License"); you may
4    * not use this file except in compliance with the License. You may
5    * obtain a copy of the License at
6    *
7    * http://www.osedu.org/licenses/ECL-2.0
8    *
9    * Unless required by applicable law or agreed to in writing,
10   * software distributed under the License is distributed on an "AS IS"
11   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12   * or implied. See the License for the specific language governing
13   * permissions and limitations under the License.
14   */
15  
16  package org.kuali.student.security.saml.service;
17  
18  import java.io.BufferedReader;
19  import java.io.InputStreamReader;
20  import java.io.StringWriter;
21  import java.io.UnsupportedEncodingException;
22  import java.net.HttpURLConnection;
23  import java.net.URL;
24  import java.net.URLEncoder;
25  import java.util.HashMap;
26  import java.util.Map;
27  
28  import javax.jws.WebService;
29  import javax.xml.transform.Transformer;
30  import javax.xml.transform.TransformerFactory;
31  import javax.xml.transform.dom.DOMSource;
32  import javax.xml.transform.stream.StreamResult;
33  
34  import org.jasig.cas.client.util.CommonUtils;
35  import org.jasig.cas.client.util.XmlUtils;
36  import org.kuali.student.security.exceptions.KSSecurityException;
37  import org.kuali.student.security.util.SamlUtils;
38  import org.opensaml.SAMLAssertion;
39  import org.w3c.dom.Document;
40  
41  @WebService(endpointInterface = "org.kuali.student.security.saml.service.SamlIssuerService", serviceName = "SamlIssuerService", portName = "SamlIssuerService", targetNamespace = "http://student.kuali.org/wsdl/security/saml")
42  public class SamlIssuerServiceImpl implements SamlIssuerService {
43      
44      private String casServerUrl;
45      private String samlIssuerForUser;
46      private String proxyCallBackUrl;
47      
48      public String validateCasProxyTicket(String proxyTicketId, String proxyTargetService) throws KSSecurityException{
49          
50          String url = constructUrl(proxyTicketId, proxyTargetService);
51          HttpURLConnection conn = null;
52          
53          try {
54              URL constructedUrl = new URL(url);
55              conn = (HttpURLConnection) constructedUrl.openConnection();
56  
57              BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
58  
59              String line;
60              StringBuffer stringBuffer = new StringBuffer(255);
61              String response;
62  
63              while ((line = in.readLine()) != null) {
64                  stringBuffer.append(line);
65              }
66              
67              response = stringBuffer.toString();
68              String error = XmlUtils.getTextForElement(response, "authenticationFailure");
69  
70              if (CommonUtils.isNotEmpty(error)) {
71                  return error;
72              }
73  
74              String user = XmlUtils.getTextForElement(response, "user");
75              String pgt  = XmlUtils.getTextForElement(response, "proxyGrantingTicket");
76              String proxies = XmlUtils.getTextForElement(response, "proxies");
77              
78              Map<String,String> samlProperties = new HashMap<String,String>();
79              samlProperties.put("user", user.trim());
80              samlProperties.put("proxyGrantingTicket", pgt.trim());
81              samlProperties.put("proxies", proxies.trim());
82              samlProperties.put("samlIssuerForUser", samlIssuerForUser.trim());
83              
84              SamlUtils.setSamlProperties(samlProperties);
85              SAMLAssertion samlAssertion = SamlUtils.createAssertion();
86              
87              Document signedSAML = SamlUtils.signAssertion(samlAssertion);
88              
89              // transform the saml DOM into a writer, and return as a string response
90              DOMSource domSource = new DOMSource(signedSAML);
91              StringWriter writer = new StringWriter();
92              StreamResult result = new StreamResult(writer);
93              
94              TransformerFactory tf = TransformerFactory.newInstance();
95              Transformer transformer;
96              
97              transformer = tf.newTransformer();
98              transformer.transform(domSource, result);
99              
100             writer.flush();
101             
102             return writer.toString();
103             
104         } catch (final Exception e) {
105             throw new KSSecurityException(e);
106         } finally {
107             if (conn != null) {
108                 conn.disconnect();
109             }
110         }
111     }
112     
113     private String constructUrl(String proxyTicketId, String proxyTargetService) throws KSSecurityException{
114         try {
115             return this.casServerUrl + (this.casServerUrl.endsWith("/") ? "" : "/") + "proxyValidate" + "?ticket=" 
116             + proxyTicketId + "&service=" + URLEncoder.encode(proxyTargetService, "UTF-8") 
117             + "&pgtUrl=" + URLEncoder.encode(proxyCallBackUrl, "UTF-8");
118         } catch (UnsupportedEncodingException e) {
119             throw new KSSecurityException(e);
120         }
121     }
122 
123     /* Use this method when not using a CAS proxy. 
124      * Example if the ProxyTicketRetrieverFilter useCasProxyMechanism = false
125      */
126     public String getSamlPrincipal(String principal) throws KSSecurityException{
127         try {      
128             Map<String,String> samlProperties = new HashMap<String,String>();
129             samlProperties.put("user", principal);
130             samlProperties.put("proxyGrantingTicket", "");
131             samlProperties.put("proxies", "");
132             samlProperties.put("samlIssuerForUser", samlIssuerForUser.trim());
133             
134             SamlUtils.setSamlProperties(samlProperties);
135             SAMLAssertion samlAssertion = SamlUtils.createAssertion();
136             
137             Document signedSAML = SamlUtils.signAssertion(samlAssertion);
138             
139             // transform the saml DOM into a writer, and return as a string response
140             DOMSource domSource = new DOMSource(signedSAML);
141             StringWriter writer = new StringWriter();
142             StreamResult result = new StreamResult(writer);
143             
144             TransformerFactory tf = TransformerFactory.newInstance();
145             Transformer transformer;
146             
147             transformer = tf.newTransformer();
148             transformer.transform(domSource, result);
149             
150             writer.flush();
151             
152             return writer.toString();
153             
154         } catch (final Exception e) {
155             throw new KSSecurityException(e);
156         } 
157 
158     }
159     
160     public String getCasServerUrl() {
161         return casServerUrl;
162     }
163 
164     public void setCasServerUrl(String casServerUrl) {
165         this.casServerUrl = casServerUrl;
166     }
167 
168     public String getSamlIssuerForUser() {
169         return samlIssuerForUser;
170     }
171 
172     public void setSamlIssuerForUser(String samlIssuerForUser) {
173         this.samlIssuerForUser = samlIssuerForUser;
174     }
175 
176     public String getProxyCallBackUrl() {
177         return proxyCallBackUrl;
178     }
179 
180     public void setProxyCallBackUrl(String proxyCallBackUrl) {
181         this.proxyCallBackUrl = proxyCallBackUrl;
182     }
183 }