/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.config.annotation.web.configurers;
import java.util.HashMap;
import java.util.Map;
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.PortMapper;
import org.springframework.security.web.PortMapperImpl;
/**
* Allows configuring a shared {@link PortMapper} instance used to determine the
* ports when redirecting between HTTP and HTTPS. The {@link PortMapper} can be
* obtained from {@link HttpSecurity#getSharedObject(Class)}.
*
* @author Rob Winch
* @since 3.2
*/
public final class PortMapperConfigurer<H extends HttpSecurityBuilder<H>> extends SecurityConfigurerAdapter<DefaultSecurityFilterChain,H> {
private PortMapper portMapper;
private Map<String, String> httpsPortMappings = new HashMap<String,String>();
/**
* Creates a new instance
*/
public PortMapperConfigurer() {
}
/**
* Allows specifying the {@link PortMapper} instance.
* @param portMapper
* @return
*/
public PortMapperConfigurer<H> portMapper(PortMapper portMapper) {
this.portMapper = portMapper;
return this;
}
/**
* Adds a port mapping
* @param httpPort the HTTP port that maps to a specific HTTPS port.
* @return {@link HttpPortMapping} to define the HTTPS port
*/
public HttpPortMapping http(int httpPort) {
return new HttpPortMapping(httpPort);
}
@Override
public void init(H http) throws Exception {
http.setSharedObject(PortMapper.class, getPortMapper());
}
/**
* Gets the {@link PortMapper} to use. If {@link #portMapper(PortMapper)}
* was not invoked, builds a {@link PortMapperImpl} using the port mappings
* specified with {@link #http(int)}.
*
* @return the {@link PortMapper} to use
*/
private PortMapper getPortMapper() {
if(portMapper == null) {
PortMapperImpl portMapper = new PortMapperImpl();
portMapper.setPortMappings(httpsPortMappings);
this.portMapper = portMapper;
}
return portMapper;
}
/**
* Allows specifying the HTTPS port for a given HTTP port when redirecting
* between HTTP and HTTPS.
*
* @author Rob Winch
* @since 3.2
*/
public final class HttpPortMapping {
private final int httpPort;
/**
* Creates a new instance
* @param httpPort
* @see PortMapperConfigurer#http(int)
*/
private HttpPortMapping(int httpPort) {
this.httpPort = httpPort;
}
/**
* Maps the given HTTP port to the provided HTTPS port and vice versa.
* @param httpsPort the HTTPS port to map to
* @return the {@link PortMapperConfigurer} for further customization
*/
public PortMapperConfigurer<H> mapsTo(int httpsPort) {
httpsPortMappings.put(String.valueOf(httpPort), String.valueOf(httpsPort));
return PortMapperConfigurer.this;
}
}
}