001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing,
013     * software distributed under the License is distributed on an
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     * KIND, either express or implied.  See the License for the
016     * specific language governing permissions and limitations
017     * under the License.
018     */
019    package org.apache.shiro.web.filter.authz;
020    
021    import javax.servlet.ServletRequest;
022    import javax.servlet.ServletResponse;
023    
024    /**
025     * Filter which requires a request to be over SSL.  Access is allowed if the request is received on the configured
026     * server {@link #setPort(int) port} <em>and</em> the
027     * {@code request.}{@link javax.servlet.ServletRequest#isSecure() isSecure()}.  If either condition is {@code false},
028     * the filter chain will not continue.
029     * <p/>
030     * The {@link #getPort() port} property defaults to {@code 443} and also additionally guarantees that the
031     * request scheme is always 'https' (except for port 80, which retains the 'http' scheme).
032     * <p/>
033     * Example config:
034     * <pre>
035     * [urls]
036     * /secure/path/** = ssl
037     * </pre>
038     *
039     * @since 1.0
040     */
041    public class SslFilter extends PortFilter {
042    
043        public static final int DEFAULT_HTTPS_PORT = 443;
044        public static final String HTTPS_SCHEME = "https";
045    
046        public SslFilter() {
047            setPort(DEFAULT_HTTPS_PORT);
048        }
049    
050        @Override
051        protected String getScheme(String requestScheme, int port) {
052            if (port == DEFAULT_HTTP_PORT) {
053                return PortFilter.HTTP_SCHEME;
054            } else {
055                return HTTPS_SCHEME;
056            }
057        }
058    
059        /**
060         * Retains the parent method's port-matching behavior but additionally guarantees that the
061         *{@code ServletRequest.}{@link javax.servlet.ServletRequest#isSecure() isSecure()}.  If the port does not match or
062         * the request is not secure, access is denied.
063         *
064         * @param request     the incoming {@code ServletRequest}
065         * @param response    the outgoing {@code ServletResponse} - ignored in this implementation
066         * @param mappedValue the filter-specific config value mapped to this filter in the URL rules mappings - ignored by this implementation.
067         * @return {@code true} if the request is received on an expected SSL port and the
068         * {@code request.}{@link javax.servlet.ServletRequest#isSecure() isSecure()}, {@code false} otherwise.
069         * @throws Exception if the call to {@code super.isAccessAllowed} throws an exception.
070         * @since 1.2
071         */
072        @Override
073        protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
074            return super.isAccessAllowed(request, response, mappedValue) && request.isSecure();
075        }
076    }