001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.jetspeed.security.impl;
018:
019: import java.io.IOException;
020: import java.security.Principal;
021: import java.security.PrivilegedAction;
022:
023: import javax.security.auth.Subject;
024: import javax.servlet.http.HttpSession;
025:
026: import org.apache.jetspeed.PortalReservedParameters;
027: import org.apache.jetspeed.administration.PortalAuthenticationConfiguration;
028: import org.apache.jetspeed.pipeline.PipelineException;
029: import org.apache.jetspeed.pipeline.valve.AbstractValve;
030: import org.apache.jetspeed.pipeline.valve.SecurityValve;
031: import org.apache.jetspeed.pipeline.valve.ValveContext;
032: import org.apache.jetspeed.request.RequestContext;
033: import org.apache.jetspeed.security.JSSubject;
034:
035: /**
036: * <p>
037: * AbstractSecurityValve
038: * </p>
039: * <p>
040: *
041: * </p>
042: * @author <a href="mailto:weaver@apache.org">Scott T. Weaver</a>
043: * @version $Id: AbstractSecurityValve.java 544402 2007-06-05 06:20:00Z taylor $
044: *
045: */
046: public abstract class AbstractSecurityValve extends AbstractValve
047: implements SecurityValve {
048: protected PortalAuthenticationConfiguration authenticationConfiguration = null;
049:
050: /**
051: *
052: * <p>
053: * getSubject
054: * </p>
055: * Should build and return a <code>javax.security.Subject</code>
056: * @param request
057: * @return Subject
058: */
059: protected abstract Subject getSubject(RequestContext request)
060: throws Exception;
061:
062: /**
063: *
064: * <p>
065: * getUserPrincipal
066: * </p>
067: * Should build and return a <code>java.security.Principal</code> that represents the user name
068: * the Subject returned from <code>getSubject()</code>
069: * @param request
070: * @return Principal
071: * @throws Exception
072: */
073: protected abstract Principal getUserPrincipal(RequestContext request)
074: throws Exception;
075:
076: /**
077: *
078: * <p>
079: * getSubjectFromSession
080: * </p>
081: *
082: * @param request
083: * @return javax.security.Subject or <code>null</code> if there is no servlet session attribute defined
084: * for the key <code>org.apache.jetspeed.PortalReservedParameters.SESSION_KEY_SUBJECT</code>.
085: */
086: protected final Subject getSubjectFromSession(RequestContext request)
087: throws Exception {
088: return (Subject) request.getRequest().getSession()
089: .getAttribute(
090: PortalReservedParameters.SESSION_KEY_SUBJECT);
091: }
092:
093: /**
094: * <p>
095: * invoke
096: * </p>
097: *
098: * <p>
099: * Uses <code>getSubject()</code> to call <code>ValveContext.invokeNext()</code> via
100: * <code>JSSubjectdoAsPrivileged()</code>. This method also takes care of setting the value of
101: * the <code>RequestContext.subject</code> property and the session attribute
102: * <code>org.apache.jetspeed.PortalReservedParameters.SESSION_KEY_SUBJECT</code>
103: * </p>
104: *
105: * @see org.apache.jetspeed.pipeline.valve.Valve#invoke(org.apache.jetspeed.request.RequestContext, org.apache.jetspeed.pipeline.valve.ValveContext)
106: * @param request
107: * @param context
108: * @throws PipelineException if the is an error encountered during any security operations.
109: */
110: public void invoke(RequestContext request, ValveContext context)
111: throws PipelineException {
112: if (isSessionExpired(request)) {
113: return; // short circuit processing and redirect
114: }
115:
116: // initialize/validate security subject
117: Subject subject;
118: try {
119: subject = getSubject(request);
120: } catch (Exception e1) {
121: throw new PipelineException(e1.getMessage(), e1);
122: }
123: request.getRequest().getSession().setAttribute(
124: PortalReservedParameters.SESSION_KEY_SUBJECT, subject);
125:
126: // set request context subject
127: request.setSubject(subject);
128:
129: // Pass control to the next Valve in the Pipeline and execute under
130: // the current subject
131: final ValveContext vc = context;
132: final RequestContext rc = request;
133: PipelineException pe = (PipelineException) JSSubject
134: .doAsPrivileged(subject, new PrivilegedAction() {
135: public Object run() {
136: try {
137: vc.invokeNext(rc);
138: return null;
139: } catch (PipelineException e) {
140: return e;
141: }
142: }
143: }, null);
144:
145: if (pe != null) {
146: throw pe;
147: }
148: }
149:
150: /**
151: * Check for hard limit session expiration time out
152: *
153: * @param request
154: * @return
155: * @throws PipelineException
156: */
157: protected boolean isSessionExpired(RequestContext request)
158: throws PipelineException {
159: if (authenticationConfiguration != null
160: && authenticationConfiguration
161: .isMaxSessionHardLimitEnabled()) {
162: HttpSession session = request.getRequest().getSession();
163: long sessionCreationTime = session.getCreationTime();
164: long currentTime = System.currentTimeMillis();
165: if ((currentTime - sessionCreationTime) > authenticationConfiguration
166: .getMsMaxSessionHardLimit()) {
167: session.invalidate();
168: String redirector = request.getRequest()
169: .getContextPath()
170: + authenticationConfiguration
171: .getTimeoutRedirectLocation();
172: // System.out.println("logging user out " + redirector + ", " + (currentTime - sessionCreationTime) + ", " + this.msMaxSessionHardLimit);
173: try {
174: request.getResponse().sendRedirect(redirector);
175: } catch (IOException e) {
176: throw new PipelineException(e);
177: }
178: return true;
179: } else {
180: // System.out.println("Not logging user out: " + (currentTime - sessionCreationTime) + ", " + this.msMaxSessionHardLimit);
181: }
182: }
183: return false;
184: }
185:
186: }
|