%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.jetspeed.portlet.sso.SSOProxyPortlet |
|
|
1 | /* |
|
2 | * Licensed to the Apache Software Foundation (ASF) under one or more |
|
3 | * contributor license agreements. See the NOTICE file distributed with |
|
4 | * this work for additional information regarding copyright ownership. |
|
5 | * The ASF licenses this file to You under the Apache License, Version 2.0 |
|
6 | * (the "License"); you may not use this file except in compliance with |
|
7 | * the License. You may obtain a copy of the License at |
|
8 | * |
|
9 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
10 | * |
|
11 | * Unless required by applicable law or agreed to in writing, software |
|
12 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
14 | * See the License for the specific language governing permissions and |
|
15 | * limitations under the License. |
|
16 | */ |
|
17 | ||
18 | /*Created on: Dec 5, 2005 */ |
|
19 | ||
20 | package org.apache.jetspeed.portlet.sso; |
|
21 | ||
22 | import java.io.IOException; |
|
23 | import java.security.AccessControlContext; |
|
24 | import java.security.AccessController; |
|
25 | import javax.portlet.ActionRequest; |
|
26 | import javax.portlet.ActionResponse; |
|
27 | import javax.portlet.PortletConfig; |
|
28 | import javax.portlet.PortletContext; |
|
29 | import javax.portlet.PortletException; |
|
30 | import javax.portlet.PortletURL; |
|
31 | import javax.portlet.RenderRequest; |
|
32 | import javax.portlet.RenderResponse; |
|
33 | import javax.security.auth.Subject; |
|
34 | ||
35 | import org.apache.jetspeed.security.JSSubject; |
|
36 | import org.apache.jetspeed.sso.SSOException; |
|
37 | import org.apache.jetspeed.sso.SSOProvider; |
|
38 | import org.apache.portals.bridges.common.ScriptPostProcess; |
|
39 | import org.apache.portals.bridges.velocity.GenericVelocityPortlet; |
|
40 | ||
41 | /** |
|
42 | * SSOProxyPortlet |
|
43 | * This portlet can be used as a bridge to any URL. |
|
44 | * It acts as a http client and therefore it can store |
|
45 | * cookies. |
|
46 | * The main purpose is that the SSOProxy portlet authenticates |
|
47 | * any SSO credential for the principal user not knowing in advance |
|
48 | * what URL the user might select. No login prompt will appear for any url |
|
49 | * in the portlet for that an SSO entry exists and the principal user has permissions. |
|
50 | * |
|
51 | * @author Roger Ruttimann <rogerrut@apache.org> |
|
52 | * |
|
53 | */ |
|
54 | 0 | public class SSOProxyPortlet extends GenericVelocityPortlet { |
55 | private PortletContext context; |
|
56 | private SSOProvider sso; |
|
57 | ||
58 | /* Re-use Proxy client inside the SSO Component */ |
|
59 | 0 | private boolean isAuthenticated = false; |
60 | ||
61 | /** Default encoding UTF-8*/ |
|
62 | 0 | public String defaultEncoding = "UTF-8"; |
63 | ||
64 | /** Block Size */ |
|
65 | static final int BLOCK_SIZE = 4096; |
|
66 | ||
67 | /** ACTION_PARAMETER_SSOPROXY*/ |
|
68 | static final String ACTION_PARAMETER_SSOPROXY = "SSOProxy"; |
|
69 | ||
70 | /** Preference values */ |
|
71 | /** DestinationURL */ |
|
72 | static final String DESTINATION_URL = "DestinationURL"; |
|
73 | ||
74 | /** SSOSite */ |
|
75 | static final String SSO_SITE = "SSOSite"; |
|
76 | ||
77 | /** ForceSSORefresh*/ |
|
78 | static final String FORCE_SSO_REFRESH = "ForceSSORefresh"; |
|
79 | ||
80 | /** Encoding*/ |
|
81 | static final String ENCODING = "Encoding"; |
|
82 | ||
83 | private String destinationURL; |
|
84 | private String ssoSite; |
|
85 | private String encoding; |
|
86 | ||
87 | public void init(PortletConfig config) throws PortletException |
|
88 | { |
|
89 | 0 | super.init(config); |
90 | 0 | context = getPortletContext(); |
91 | 0 | sso = (SSOProvider)context.getAttribute("cps:SSO"); |
92 | 0 | if (null == sso) |
93 | { |
|
94 | 0 | throw new PortletException("Failed to find SSO Provider on portlet initialization"); |
95 | } |
|
96 | ||
97 | 0 | } |
98 | ||
99 | public void processAction(ActionRequest request, ActionResponse actionResponse) |
|
100 | throws PortletException, IOException |
|
101 | { |
|
102 | 0 | String ssoProxyAction = request.getParameter(ACTION_PARAMETER_SSOPROXY); |
103 | // System.out.println("SSOProxy Action value [" + ssoProxyAction + "]"); |
|
104 | ||
105 | 0 | if ( ssoProxyAction != null && ssoProxyAction.length() > 0) |
106 | 0 | this.destinationURL = ssoProxyAction; |
107 | else |
|
108 | 0 | this.destinationURL = request.getParameter(DESTINATION_URL); |
109 | ||
110 | ||
111 | 0 | this.ssoSite = request.getParameter(SSO_SITE); |
112 | 0 | this.encoding = request.getParameter(ENCODING); |
113 | 0 | if (this.encoding == null) |
114 | 0 | this.encoding = class="keyword">this.defaultEncoding; |
115 | ||
116 | // save the prefs |
|
117 | 0 | super.processAction(request, actionResponse); |
118 | 0 | } |
119 | ||
120 | public void doView(RenderRequest request, RenderResponse response) |
|
121 | throws PortletException, IOException |
|
122 | { |
|
123 | 0 | String forceRefresh = request.getPreferences().getValue(FORCE_SSO_REFRESH, "false"); |
124 | ||
125 | 0 | if (destinationURL == null || destinationURL.length() == 0) |
126 | { |
|
127 | // No destination configured Switch to configure View |
|
128 | 0 | request.setAttribute(PARAM_VIEW_PAGE, this.getPortletConfig().getInitParameter(PARAM_EDIT_PAGE)); |
129 | 0 | setupPreferencesEdit(request, response); |
130 | 0 | super.doView(request, response); |
131 | 0 | return; |
132 | } |
|
133 | ||
134 | // Set the content type |
|
135 | 0 | response.setContentType("text/html"); |
136 | ||
137 | /* |
|
138 | * Call into the SSO Proxy and process the result page |
|
139 | */ |
|
140 | 0 | boolean doRefresh = false; |
141 | 0 | if ( (forceRefresh.compareToIgnoreCase("TRUE") == 0) || this.isAuthenticated == false) |
142 | 0 | doRefresh = true; |
143 | ||
144 | try |
|
145 | { |
|
146 | 0 | StringBuffer page= new StringBuffer(); |
147 | 0 | Subject subject = getSubject(); |
148 | 0 | if (ssoSite == null || ssoSite.length() ==0) |
149 | 0 | page.append(sso.useSSO(subject, destinationURL,doRefresh)); |
150 | else |
|
151 | 0 | page.append(sso.useSSO(subject, destinationURL,ssoSite, doRefresh)); |
152 | ||
153 | // Authentication done at least once |
|
154 | 0 | this.isAuthenticated = true; |
155 | /* |
|
156 | bis.mark(BLOCK_SIZE); |
|
157 | String pageEncoding = getContentCharSet(bis); |
|
158 | if (pageEncoding == null) |
|
159 | { |
|
160 | pageEncoding = encoding; |
|
161 | } |
|
162 | |
|
163 | Reader read = new InputStreamReader(bis, encoding); |
|
164 | |
|
165 | |
|
166 | char[] bytes = new char[BLOCK_SIZE]; |
|
167 | |
|
168 | int len = read.read(bytes, 0, BLOCK_SIZE); |
|
169 | while (len > 0) |
|
170 | { |
|
171 | page.append(bytes, 0, len); |
|
172 | len = read.read(bytes, 0, BLOCK_SIZE); |
|
173 | } |
|
174 | |
|
175 | //Done |
|
176 | read.close(); |
|
177 | */ |
|
178 | // Rewrite |
|
179 | // Post Process for generated page |
|
180 | 0 | PortletURL actionURL = response.createActionURL(); |
181 | 0 | ScriptPostProcess processor = new ScriptPostProcess(); |
182 | 0 | processor.setInitalPage(page); |
183 | 0 | processor.postProcessPage(actionURL, ACTION_PARAMETER_SSOPROXY); |
184 | 0 | String finalPage = processor.getFinalizedPage(); |
185 | ||
186 | // Write the page |
|
187 | 0 | response.getWriter().println(finalPage); |
188 | ||
189 | } |
|
190 | 0 | catch (SSOException e) |
191 | { |
|
192 | 0 | response.getWriter().println("<P>Error rendering page. Error message<BR>" + e.getMessage() + "</P>"); |
193 | ||
194 | 0 | this.destinationURL =""; |
195 | 0 | } |
196 | 0 | } |
197 | ||
198 | ||
199 | public void doEdit(RenderRequest request, RenderResponse response) |
|
200 | throws PortletException, IOException |
|
201 | { |
|
202 | 0 | super.doEdit(request, response); |
203 | 0 | } |
204 | ||
205 | /* |
|
206 | * Helper methods |
|
207 | */ |
|
208 | private Subject getSubject() |
|
209 | { |
|
210 | 0 | AccessControlContext context = AccessController.getContext(); |
211 | 0 | return JSSubject.getSubject(context); |
212 | } |
|
213 | ||
214 | /* |
|
215 | private String getContentCharSet(InputStream is) throws IOException |
|
216 | { |
|
217 | if (!is.markSupported()) |
|
218 | { |
|
219 | return null; |
|
220 | } |
|
221 | ||
222 | byte[] buf = new byte[BLOCK_SIZE]; |
|
223 | try |
|
224 | { |
|
225 | is.read(buf, 0, BLOCK_SIZE); |
|
226 | String content = new String(buf, "ISO-8859-1"); |
|
227 | String lowerCaseContent = content.toLowerCase(); |
|
228 | int startIndex = lowerCaseContent.indexOf("<head"); |
|
229 | if (startIndex == -1) |
|
230 | { |
|
231 | startIndex = 0; |
|
232 | } |
|
233 | int endIndex = lowerCaseContent.indexOf("</head"); |
|
234 | if (endIndex == -1) |
|
235 | { |
|
236 | endIndex = content.length(); |
|
237 | } |
|
238 | content = content.substring(startIndex, endIndex); |
|
239 | ||
240 | StringTokenizer st = new StringTokenizer(content, "<>"); |
|
241 | while (st.hasMoreTokens()) |
|
242 | { |
|
243 | String element = st.nextToken(); |
|
244 | String lowerCaseElement = element.toLowerCase(); |
|
245 | if (lowerCaseElement.startsWith("meta") && lowerCaseElement.indexOf("content-type") > 0) |
|
246 | { |
|
247 | StringTokenizer est = new StringTokenizer(element, " =\"\';"); |
|
248 | while (est.hasMoreTokens()) |
|
249 | { |
|
250 | if (est.nextToken().equalsIgnoreCase("charset")) |
|
251 | { |
|
252 | if (est.hasMoreTokens()) |
|
253 | { |
|
254 | is.reset(); |
|
255 | return est.nextToken(); |
|
256 | } |
|
257 | } |
|
258 | } |
|
259 | } |
|
260 | } |
|
261 | } |
|
262 | catch (IOException e) |
|
263 | { |
|
264 | } |
|
265 | ||
266 | is.reset(); |
|
267 | ||
268 | return null; |
|
269 | } |
|
270 | */ |
|
271 | ||
272 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |