📄 casfilter.java
字号:
/* * Copyright (c) 2000-2003 Yale University. All rights reserved. * * THIS SOFTWARE IS PROVIDED "AS IS," AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE EXPRESSLY * DISCLAIMED. IN NO EVENT SHALL YALE UNIVERSITY OR ITS EMPLOYEES BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED, THE COSTS OF * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH * DAMAGE. * * Redistribution and use of this software in source or binary forms, * with or without modification, are permitted, provided that the * following conditions are met: * * 1. Any redistribution must include the above copyright notice and * disclaimer and this list of conditions in any related documentation * and, if feasible, in the redistributed software. * * 2. Any redistribution must include the acknowledgment, "This product * includes software developed by Yale University," in any related * documentation and, if feasible, in the redistributed software. * * 3. The names "Yale" and "Yale University" must not be used to endorse * or promote products derived from this software. */package edu.yale.its.tp.cas.client.filter;import java.io.*;import java.net.*;import java.util.*;import javax.servlet.*;import javax.servlet.http.*;import edu.yale.its.tp.cas.client.*;import edu.yale.its.tp.cas.client.filter.*;import javax.xml.parsers.ParserConfigurationException;import org.xml.sax.SAXException;/** * <p>Protects web-accessible resources with CAS.</p> * * <p>The following filter initialization parameters are declared in * <code>web.xml</code>:</p> * * <ul> * <li><code>edu.yale.its.tp.cas.client.filter.loginUrl</code>: URL to * login page on CAS server. (Required)</li> * <li><code>edu.yale.its.tp.cas.client.filter.validateUrl</code>: URL * to validation URL on CAS server. (Required)</li> * <li><code>edu.yale.its.tp.cas.client.filter.serviceUrl</code>: URL * of this service. (Required if <code>serverName</code> is not * specified)</li> * <li><code>edu.yale.its.tp.cas.client.filter.serverName</code>: full * hostname with port number (e.g. <code>www.foo.com:8080</code>). * Port number isn't required if it is standard (80 for HTTP, 443 for * HTTPS). (Required if <code>serviceUrl</code> is not specified)</li> * <li><code>edu.yale.its.tp.cas.client.filter.authorizedProxy</code>: * whitespace-delimited list of valid proxies through which authentication * may have proceeded. One one proxy must match. (Optional. If nothing * is specified, the filter will only accept service tickets – not * proxy tickets.)</li> * <li><code>edu.yale.its.tp.cas.client.filter.renew</code>: value of * CAS "renew" parameter. Bypasses single sign-on and requires user * to provide CAS with his/her credentials again. (Optional. If nothing * is specified, this defaults to false.)</li> * <li><code>edu.yale.its.tp.cas.client.filter.wrapRequest</code>: * wrap the <code>HttpServletRequest</code> object, overriding the * <code>getRemoteUser()</code> method. When set to "true", * <code>request.getRemoteUser()</code> will return the username of the * currently logged-in CAS user. (Optional. If nothing is specified, * this defaults to false.)</li> * </ul> * * <p>The logged-in username is set in the session attribute defined by * the value of <code>CAS_FILTER_USER</code> and may be accessed from within * your application either by setting <code>wrapRequest</code> and calling * <code>request.getRemoteUser()</code>, or by calling * <code>session.getAttribute(CASFilter.CAS_FILTER_USER)</code>.</p> * * @author Shawn Bayern */public class CASFilter implements Filter { //********************************************************************* // Constants /** Session attribute in which the username is stored */ public final static String CAS_FILTER_USER = "edu.yale.its.tp.cas.client.filter.user"; //********************************************************************* // Configuration state private String casLogin, casValidate, casAuthorizedProxy, casServiceUrl, casRenew, casServerName; private boolean wrapRequest; //********************************************************************* // Initialization public void init(FilterConfig config) throws ServletException { casLogin = config.getInitParameter( "edu.yale.its.tp.cas.client.filter.loginUrl"); casValidate = config.getInitParameter( "edu.yale.its.tp.cas.client.filter.validateUrl"); casServiceUrl = config.getInitParameter( "edu.yale.its.tp.cas.client.filter.serviceUrl"); casAuthorizedProxy = config.getInitParameter( "edu.yale.its.tp.cas.client.filter.authorizedProxy"); casRenew = config.getInitParameter("edu.yale.its.tp.cas.client.filter.renew"); casServerName = config.getInitParameter( "edu.yale.its.tp.cas.client.filter.serverName"); wrapRequest = Boolean.valueOf(config.getInitParameter( "edu.yale.its.tp.cas.client.filter.wrapRequest")).booleanValue(); } //********************************************************************* // Filter processing public void doFilter( ServletRequest request, ServletResponse response, FilterChain fc) throws ServletException, IOException { // make sure we've got an HTTP request if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) throw new ServletException("CASFilter protects only HTTP resources"); // Wrap the request if desired if(wrapRequest) { request = new CASFilterRequestWrapper((HttpServletRequest)request); } HttpSession session = ((HttpServletRequest)request).getSession(); // if our attribute's already present, don't do anything if (session != null && session.getAttribute(CAS_FILTER_USER) != null) { fc.doFilter(request, response); return; } // otherwise, we need to authenticate via CAS String ticket = request.getParameter("ticket"); // no ticket? abort request processing and redirect if (ticket == null || ticket.equals("")) { if (casLogin == null) { throw new ServletException( "When CASFilter protects pages that do not receive a 'ticket' " + "parameter, it needs a edu.yale.its.tp.cas.client.filter.loginUrl " + "filter parameter"); } ((HttpServletResponse)response).sendRedirect( casLogin + "?service=" + getService((HttpServletRequest)request) + ((casRenew != null && !casRenew.equals("")) ? "&renew=" + casRenew : "")); // abort chain return; } // Yay, ticket! Validate it. String user = getAuthenticatedUser((HttpServletRequest)request); if (user == null) throw new ServletException("Unexpected CAS authentication error"); // Store the authenticated user in the session if (session != null) // probably unncessary session.setAttribute(CAS_FILTER_USER, user); // continue processing the request fc.doFilter(request, response); } //********************************************************************* // Destruction public void destroy() { } //********************************************************************* // Utility methods /** * Converts a ticket parameter to a username, taking into account an * optionally configured trusted proxy in the tier immediately in front * of us. */ private String getAuthenticatedUser(HttpServletRequest request) throws ServletException { ProxyTicketValidator pv = null; try { pv = new ProxyTicketValidator(); pv.setCasValidateUrl(casValidate); pv.setServiceTicket(request.getParameter("ticket")); pv.setService(getService(request)); pv.setRenew(Boolean.valueOf(casRenew).booleanValue()); pv.validate(); if (!pv.isAuthenticationSuccesful()) throw new ServletException( "CAS authentication error: " + pv.getErrorCode() + ": " + pv.getErrorMessage()); if (pv.getProxyList().size() != 0) { // ticket was proxied if (casAuthorizedProxy == null) { throw new ServletException("this page does not accept proxied tickets"); } else { boolean authorized = false; String proxy = (String)pv.getProxyList().get(0); StringTokenizer casProxies = new StringTokenizer(casAuthorizedProxy); while (casProxies.hasMoreTokens()) { if (proxy.equals(casProxies.nextToken())) { authorized = true; break; } } if (!authorized) { throw new ServletException( "unauthorized top-level proxy: '" + pv.getProxyList().get(0) + "'"); } } } return pv.getUser(); } catch (SAXException ex) { String xmlResponse = ""; if (pv != null) xmlResponse = pv.getResponse(); throw new ServletException(ex + " " + xmlResponse); } catch (ParserConfigurationException ex) { throw new ServletException(ex); } catch (IOException ex) { throw new ServletException(ex); } } /** * Returns either the configured service or figures it out for the current * request. The returned service is URL-encoded. */ private String getService(HttpServletRequest request) throws ServletException { // ensure we have a server name or service name if (casServerName == null && casServiceUrl == null) throw new ServletException( "need one of the following configuration " + "parameters: edu.yale.its.tp.cas.client.filter.serviceUrl or " + "edu.yale.its.tp.cas.client.filter.serverName"); // use the given string if it's provided if (casServiceUrl != null) return URLEncoder.encode(casServiceUrl); else // otherwise, return our best guess at the service return Util.getService(request, casServerName); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -