KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > netui > tomcat > PageflowHelperImpl


1 /*
2  * Copyright 2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * $Header:$
17  */

18 package org.apache.beehive.netui.tomcat;
19
20 import org.apache.catalina.*;
21 import org.apache.catalina.deploy.SecurityConstraint;
22 import org.apache.catalina.deploy.SecurityCollection;
23 import org.apache.catalina.authenticator.Constants;
24 import org.apache.coyote.tomcat5.CoyoteConnector;
25
26 import javax.servlet.http.HttpServletRequest JavaDoc;
27 import javax.servlet.http.HttpServletResponse JavaDoc;
28 import javax.servlet.ServletContext JavaDoc;
29 import javax.security.auth.login.LoginException JavaDoc;
30 import java.io.IOException JavaDoc;
31
32 public class PageflowHelperImpl implements PageflowHelper
33 {
34
35     private HttpRequest _request = null;
36     private HttpResponse _response = null;
37     private PageflowValve _valve = null;
38
39     public void login( String JavaDoc username, String JavaDoc password, HttpServletRequest JavaDoc request )
40             throws LoginException JavaDoc
41     {
42         _valve.login( username, password, _request, _response );
43     }
44
45     public void logout(boolean invalidateSessions, HttpServletRequest JavaDoc request)
46     {
47         _valve.logout( invalidateSessions, _request, _response );
48     }
49
50     /**
51      * Causes the server to do a security check for the given URI. If required, it does a redirect to
52      * change the scheme (http/https).
53      *
54      * @param uri
55      * @param request
56      * @param response
57      * @return <code>true</code> if a redirect occurred.
58      */

59     public boolean doSecurityRedirect( String JavaDoc uri, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response,
60                                        ServletContext JavaDoc servletContext )
61     {
62         SecurityConstraint constraint = findBestMatchSecurityConstraint( uri, _valve.getContext() );
63
64         if ( constraint == null )
65             return false;
66
67         try
68         {
69             return _valve.checkSecurity(_request, _response, constraint);
70         }
71         catch ( IOException JavaDoc e )
72         {
73             e.printStackTrace(); // TODO?
74
return false;
75         }
76     }
77
78     /**
79      * Tell whether a web application resource requires a secure transport protocol. This is
80      * determined from web.xml; for example, the following block specifies that all resources under
81      * /login require a secure transport protocol.
82      * <pre>
83      * &lt;security-constraint&gt;
84      * &lt;web-resource-collection&gt;
85      * &lt;web-resource-name&gt;Secure PageFlow - begin&lt;/web-resource-name&gt;
86      * &lt;url-pattern&gt;/login/*&lt;/url-pattern&gt;
87      * &lt;/web-resource-collection&gt;
88      * &lt;user-data-constraint&gt;
89      * &lt;transport-guarantee&gt;CONFIDENTIAL&lt;/transport-guarantee&gt;
90      * &lt;/user-data-constraint&gt;
91      * &lt;/security-constraint&gt;
92      * </pre>
93      *
94      * @param uri a webapp-relative URI for a resource. There must not be query parameters or a scheme
95      * on the URI.
96      * @param request the current request.
97      * @return <code>Boolean.TRUE</code> if a transport-guarantee of <code>CONFIDENTIAL</code> or
98      * <code>INTEGRAL</code> is associated with the given resource; <code>Boolean.FALSE</code>
99      * a transport-guarantee of <code>NONE</code> is associated with the given resource; or
100      * <code>null</code> if there is no transport-guarantee associated with the given resource.
101      */

102     public Boolean JavaDoc isSecureResource( String JavaDoc uri, HttpServletRequest JavaDoc request )
103     {
104         Boolean JavaDoc result = null;
105         Context JavaDoc ctx = _valve.getContext();
106
107         SecurityConstraint constraint = findBestMatchSecurityConstraint( uri, ctx );
108         if ( constraint != null )
109         {
110             String JavaDoc userDataConstraint = constraint.getUserConstraint();
111             if ( userDataConstraint != null )
112             {
113                 String JavaDoc transportGuarantee = userDataConstraint;
114                 if ( transportGuarantee.equalsIgnoreCase( Constants.CONFIDENTIAL_TRANSPORT )
115                      || transportGuarantee.equalsIgnoreCase( Constants.INTEGRAL_TRANSPORT ) )
116                 {
117 // cache.put( uri, PROTOCOL_SECURE );
118
return Boolean.TRUE;
119                 }
120                 else if ( transportGuarantee.equalsIgnoreCase( Constants.NONE_TRANSPORT ) )
121                 {
122 // cache.put( uri, PROTOCOL_UNSECURE );
123
return Boolean.FALSE;
124                 }
125             }
126         }
127
128         return result;
129     }
130
131     public int getListenPort( HttpServletRequest JavaDoc request )
132     {
133         int port = -1;
134         Connector conn = _request.getConnector();
135         if ( conn instanceof CoyoteConnector )
136         {
137             CoyoteConnector cc = (CoyoteConnector)conn;
138             if ( !cc.getSecure() )
139             {
140                 // this is the regular connector, so use it's port
141
port = cc.getPort();
142             }
143             else
144             {
145                 // look for a non-secure connector on this service with our port as the redirectPort
146
Service svc = cc.getService();
147                 Connector[] connectors = svc.findConnectors();
148                 for ( int i=0; i<connectors.length; i++ )
149                 {
150                     if ( connectors[i] != cc && connectors[i] instanceof CoyoteConnector &&
151                             !connectors[i].getSecure() && connectors[i].getRedirectPort() == cc.getPort() )
152                     {
153                         port = ((CoyoteConnector)connectors[i]).getPort();
154                         break;
155                     }
156                 }
157                 
158                 if ( port == -1 )
159                 {
160                     // last resort, just use the first non-secure connector we find
161
for ( int i=0; i<connectors.length; i++ )
162                     {
163                         if ( connectors[i] != cc && connectors[i] instanceof CoyoteConnector &&
164                                 !connectors[i].getSecure() )
165                         {
166                             port = ((CoyoteConnector)connectors[i]).getPort();
167                             break;
168                         }
169                     }
170                 }
171             }
172         }
173         return port;
174     }
175
176     public int getSecureListenPort( HttpServletRequest JavaDoc request )
177     {
178         int port = -1;
179         Connector conn = _request.getConnector();
180         if ( conn instanceof CoyoteConnector )
181         {
182             CoyoteConnector cc = (CoyoteConnector)conn;
183             if ( cc.getSecure() )
184             {
185                 // this is the secure connector, so use it's port
186
port = cc.getPort();
187             }
188             else
189             {
190                 // use the redirect port specified in the connector configuration
191
port = cc.getRedirectPort();
192             }
193         }
194         else
195         {
196             // use the redirect port specified in the connector configuration, even if not a coyote connector
197
port = conn.getRedirectPort();
198         }
199         return port;
200     }
201
202
203     /**
204      * Determine the best matching security constraint. An exact url pattern match will always win; followed
205      * by the longest matching path pattern (i.e. /foo/bar/*); followed by a file extension match.
206      * @param uri
207      * @param ctx
208      * @return
209      */

210     private SecurityConstraint findBestMatchSecurityConstraint( String JavaDoc uri, Context JavaDoc ctx )
211     {
212         // NOTE: org.apache.catalina.authenticator.AuthenticatorBase.findConstraint() has a similar method but it only
213
// finds the first SecurityConstraint that matches, not necessarily the best match
214

215         SecurityConstraint[] securityConstraints = ctx.findConstraints();
216
217         if ( securityConstraints == null || securityConstraints.length == 0 )
218         {
219             return null;
220         }
221
222         String JavaDoc fileExtension = getFileExtension( uri );
223         SecurityConstraint matchingConstraint = null;
224         int matchingPathLen = -1;
225         boolean foundExact = false;
226
227         for ( int i = 0; i < securityConstraints.length && ! foundExact; ++i )
228         {
229             SecurityConstraint securityConstraint = securityConstraints[i];
230             SecurityCollection[] wrcs = securityConstraint.findCollections();
231
232             for ( int j = 0; j < wrcs.length && ! foundExact; ++j )
233             {
234                 String JavaDoc[] urlPatterns = wrcs[j].findPatterns();
235
236                 for ( int k = 0; k < urlPatterns.length; ++k )
237                 {
238                     String JavaDoc pattern = urlPatterns[k];
239
240                     if ( pattern.length() > matchingPathLen && pattern.endsWith( "/*" ) )
241                     {
242                         if ( uri.startsWith( pattern.substring( 0, pattern.length() - 1 ) ) )
243                         {
244                             matchingConstraint = securityConstraint;
245                             matchingPathLen = pattern.length();
246                         }
247                     }
248                     else if ( matchingConstraint == null && pattern.equals( "*." + fileExtension ) )
249                     {
250                         matchingConstraint = securityConstraint;
251                     }
252                     else if ( pattern.equals( uri ) )
253                     {
254                         matchingConstraint = securityConstraint;
255                         foundExact = true;
256                         break;
257                     }
258                 }
259             }
260         }
261
262         return matchingConstraint;
263     }
264
265     private static String JavaDoc getFileExtension( String JavaDoc filename )
266     {
267         int lastDot = filename.lastIndexOf( '.' );
268         return lastDot != -1 ? filename.substring( lastDot + 1 ) : "";
269     }
270
271     void initRequest( HttpRequest request, HttpResponse response, PageflowValve valve )
272     {
273         _request = request;
274         _response = response;
275         _valve = valve;
276     }
277 }
278
Popular Tags