📄 accessinterceptor.java
字号:
/* * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 1999 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, 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 OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * * [Additional notices, if required by prior licensing conditions] * */ package org.apache.tomcat.request;import org.apache.tomcat.core.*;import org.apache.tomcat.core.Constants;import org.apache.tomcat.util.*;import javax.servlet.http.*;import javax.servlet.*;import java.io.*;import java.util.*;// XXX maybe it's a good idea to use a different model for adding secuirty// constraints - we use Container now because we want to generalize all// per/URL properties. /** * Access control - find if a request matches any web-resource-collection * and set the "required" attributes. * * The spec requires additive checking ( i.e. there is no "best match" * defined, but "all requests that contain a request path that mathces the * URL pattern in the resource collection are subject to the constraing" ). * * In "integrated" mode this interceptor will be no-op, we'll use the * web server ( assuming we can map the security to web-server equivalent * concepts - I think we can do that, but need to experiment with that) */public class AccessInterceptor extends BaseInterceptor { ContextManager cm; // Security mapping note int secMapNote; // Required roles attribute int reqRolesNote; int reqTransportNote; public AccessInterceptor() { } /* -------------------- Initialization -------------------- */ /** Set the context manager. To keep it simple we don't support * dynamic add/remove for this interceptor. */ public void engineInit(ContextManager cm) throws TomcatException { super.engineInit( cm ); this.cm=cm; // set-up a per/container note for maps try { secMapNote = cm.getNoteId( ContextManager.CONTAINER_NOTE, "map.security"); // Used for inter-module communication - required role, tr reqRolesNote = cm.getNoteId( ContextManager.REQUEST_NOTE, "required.roles"); reqTransportNote = cm.getNoteId( ContextManager.REQUEST_NOTE, "required.transport"); } catch( TomcatException ex ) { ex.printStackTrace(); throw new RuntimeException( "Invalid state "); } } public void contextInit( Context ctx) throws TomcatException { String login_type=ctx.getAuthMethod(); if( debug > 0 ) log( "Init " + ctx.getHost() + " " + ctx.getPath() + " " + login_type ); if( null==ctx.getErrorPage( "403" )) { ctx.addServlet( new SSLRequiredHandler()); ctx.addErrorPage( "403", "tomcat.sslRequiredHandler"); } if( "FORM".equals( login_type )) { String page=ctx.getFormLoginPage(); String errorPage = ctx.getFormErrorPage(); if(page==null || errorPage==null) { ctx.log( "Form login without form pages, defaulting to basic " + page + " " + errorPage); // if the user specifies a 401 page do nothing if( null==ctx.getErrorPage( "401" )) { ctx.addServlet( new BasicAuthHandler()); ctx.addErrorPage( "401", "tomcat.basicAuthHandler"); } return; } // Workaround for common error - no "/" at start of page if( ! page.startsWith("/")) { ctx.log("FORM: login page doesn't start with / " + page ); page="/" + page; } if( ! errorPage.startsWith("/")) { ctx.log("FORM: error page doesn't start with / " + errorPage ); errorPage="/" + errorPage; } String cpath=ctx.getPath(); // Workaround for common error - ctx path included if( page.startsWith( cpath ) ) { if( ! ("".equals(cpath) || "/".equals(cpath)) ) ctx.log("FORM: WARNING, login page starts with " + "context path " + page + " " + cpath ); } else page= cpath + page; if( errorPage.startsWith( cpath ) ) { if( ! ("/".equals(cpath) || "".equals( cpath )) ) ctx.log("FORM: WARNING, error page starts with " + "context path " + errorPage); } else errorPage= cpath + errorPage; // Adjust login and error paths - avoid computations in handlers ctx.setFormLoginPage( page ); ctx.setFormErrorPage( errorPage ); FormAuthHandler formH=new FormAuthHandler(); formH.setDebug(0); ctx.addServlet( formH ); ctx.addServlet( new FormSecurityCheckHandler() ); ctx.addErrorPage( "401", "tomcat.formAuthHandler"); // Add mapping for the POST handler String pageP=page.substring( cpath.length()); int lastS=pageP.lastIndexOf( "/" ); String location="/j_security_check"; if( lastS > 0 ) { location=pageP.substring( 0, lastS) + "/j_security_check"; } ctx.addServletMapping( location, "tomcat.formSecurityCheck"); if( debug > 0 ) ctx.log( "Map " + location + " to tomcat.formSecurityCheck for " + page); } else if( "BASIC".equals( login_type )) { if( null==ctx.getErrorPage( "401" )) { ctx.addServlet( new BasicAuthHandler()); ctx.addErrorPage( "401", "tomcat.basicAuthHandler"); } } else { // if unknown, leave the normal 404 error handler to deal // with unauthorized access. } } // XXX not implemented - will deal with that after everything else works. public void removeContainer( Container ct ) throws TomcatException { } /** */ public void addContainer( Container ct ) throws TomcatException { Context ctx=ct.getContext(); Container ctxCt=ctx.getContainer(); SecurityConstraints ctxSecurityC=(SecurityConstraints)ctxCt. getNote( secMapNote ); if( ctxSecurityC==null) ctxCt.setNote( secMapNote, new SecurityConstraints() ); if( ct.getRoles()!=null || ct.getTransport()!=null ) { if( debug > 0 ) log( "addContainer() " + ctx.getHost() + " " + ctx.getPath() + " " + ct.getPath() ); ctxSecurityC.addContainer( ct ); } } /* -------------------- Request mapping -------------------- */ /** Check if this request requires auth, and if so check the roles. */ public int requestMap( Request req ) { Context ctx=req.getContext(); SecurityConstraints ctxSec=(SecurityConstraints)ctx.getContainer(). getNote( secMapNote ); if( ctxSec.patterns==0 ) return 0; // fast exit String reqURI = req.getRequestURI(); String ctxPath= ctx.getPath(); String path=reqURI.substring( ctxPath.length()); String method=req.getMethod(); if( debug > 1 ) log( "checking " + path ); for( int i=0; i< ctxSec.patterns ; i++ ) { Container ct=ctxSec.securityPatterns[i]; if( match( ct, path, method ) ) { String roles[]=ct.getRoles(); String methods[]=ct.getMethods(); String transport=ct.getTransport(); if( debug>0) { StringBuffer sb=new StringBuffer("matched "); sb.append(ct.getPath()).append(" "); if(methods!=null) for( int j=0; j< methods.length; j++ )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -