@ -20,6 +20,7 @@ import net.sf.acegisecurity.intercept.web.AuthenticationEntryPoint;
import org.springframework.beans.factory.InitializingBean ;
import org.springframework.beans.factory.InitializingBean ;
import java.io.IOException ;
import java.io.IOException ;
import java.util.HashMap ;
import java.util.HashMap ;
import java.util.Iterator ;
import java.util.Iterator ;
import java.util.Map ;
import java.util.Map ;
@ -32,8 +33,31 @@ import javax.servlet.http.HttpServletResponse;
/ * *
/ * *
* < p >
* Used by the < code > SecurityEnforcementFilter < / code > to commence
* Used by the < code > SecurityEnforcementFilter < / code > to commence
* authentication via the { @link AuthenticationProcessingFilter } .
* authentication via the { @link AuthenticationProcessingFilter } . This object
* holds the location of the login form , relative to the web app context path ,
* and is used to commence a redirect to that form .
* < / p >
*
* < p >
* By setting the < em > forceHttps < / em > property to true , you may configure the
* class to force the protocol used for the login form to be
* < code > https < / code > , even if the original intercepted request for a resource
* used the < code > http < / code > protocol . When this happens , after a successful
* login ( via https ) , the original resource will still be accessed as http ,
* via the original request URL . For the forced https feature to work , the
* class must have a valid mapping from an http port in the original request
* to an https port for the login page ( the same server name will be used ,
* only the scheme and port will be changed ) . By default , http requests to
* port 80 will be mapped to login page https requests on port 443 ( standard
* https port ) , and port 8080 will be mapped to port 8443 . These mappings may
* be customized by setting the < em > httpsPortMappings < / em > property . Any
* intercepted http request on a port which does not have a mapping will
* result in the protocol remaining as http . Any intercepted request which is
* already https will always result in the login page being accessed as https ,
* regardless of the state of the < em > forceHttps < / em > property .
* < / p >
*
*
* @author Ben Alex
* @author Ben Alex
* @author colin sampaleanu
* @author colin sampaleanu
@ -43,24 +67,95 @@ public class AuthenticationProcessingFilterEntryPoint
implements AuthenticationEntryPoint , InitializingBean {
implements AuthenticationEntryPoint , InitializingBean {
//~ Instance fields ========================================================
//~ Instance fields ========================================================
/ * *
private HashMap httpsPortMappings ;
* The URL where the < code > AuthenticationProcessingFilter < / code > login page
* can be found .
* /
private String loginFormUrl ;
private String loginFormUrl ;
private boolean forceHttps = false ;
private boolean forceHttps = false ;
private HashMap httpsPortMapping ;
//~ Methods ===== ===========================================================
//~ Constructors ===========================================================
public AuthenticationProcessingFilterEntryPoint ( ) {
public AuthenticationProcessingFilterEntryPoint ( ) {
httpsPortMapping = new HashMap ( ) ;
httpsPortMappings = new HashMap ( ) ;
httpsPortMapping . put ( new Integer ( 80 ) , new Integer ( 443 ) ) ;
httpsPortMappings . put ( new Integer ( 80 ) , new Integer ( 443 ) ) ;
httpsPortMapping . put ( new Integer ( 8080 ) , new Integer ( 8443 ) ) ;
httpsPortMappings . put ( new Integer ( 8080 ) , new Integer ( 8443 ) ) ;
}
//~ Methods ================================================================
/ * *
* Set to true to force login form access to be via https . If this value is
* ture ( the default is false ) , and the incoming request for the protected
* resource which triggered the interceptor was not already
* < code > https < / code > , then
*
* @param forceHttps
*
* @todo Generated comment
* /
public void setForceHttps ( boolean forceHttps ) {
this . forceHttps = forceHttps ;
}
public boolean getForceHttps ( ) {
return forceHttps ;
}
}
/ * *
* < p >
* Set to override the default http port to https port mappings of 80 : 443 ,
* and 8080 : 8443 .
* < / p >
* In a Spring XML ApplicationContext , a definition would look something
* like this :
* < pre >
* & lt ; property name = "httpsPortMapping" >
* & lt ; map >
* & lt ; entry key = "80" > & lt ; value > 443 & lt ; / value > & lt ; / entry >
* & lt ; entry key = "8080" > & lt ; value > 8443 & lt ; / value > & lt ; / entry >
* & lt ; / map >
* & lt ; / property >
* < / pre >
*
* @param newMappings A Map consisting of String keys and String values ,
* where for each entry the key is the string representation of an
* integer http port number , and the value is the string
* representation of the corresponding integer https port number .
*
* @throws IllegalArgumentException if input map does not consist of String
* keys and values , each representing an integer port number in
* the range 1 - 65535 for that mapping .
* /
public void setHttpsPortMappings ( HashMap newMappings ) {
httpsPortMappings . clear ( ) ;
Iterator it = newMappings . entrySet ( ) . iterator ( ) ;
while ( it . hasNext ( ) ) {
Map . Entry entry = ( Map . Entry ) it . next ( ) ;
Integer httpPort = new Integer ( ( String ) entry . getKey ( ) ) ;
Integer httpsPort = new Integer ( ( String ) entry . getValue ( ) ) ;
if ( ( httpPort . intValue ( ) < 1 ) | | ( httpPort . intValue ( ) > 65535 )
| | ( httpsPort . intValue ( ) < 1 ) | | ( httpsPort . intValue ( ) > 65535 ) ) {
throw new IllegalArgumentException (
"one or both ports out of legal range: " + httpPort + ", "
+ httpsPort ) ;
}
httpsPortMappings . put ( httpPort , httpsPort ) ;
if ( httpsPortMappings . size ( ) < 1 ) {
throw new IllegalArgumentException ( "must map at least one port" ) ;
}
}
}
/ * *
* The URL where the < code > AuthenticationProcessingFilter < / code > login page
* can be found . Should be relative to the web - app context path , and
* include a leading < code > / < / code >
*
* @param loginFormUrl
* /
public void setLoginFormUrl ( String loginFormUrl ) {
public void setLoginFormUrl ( String loginFormUrl ) {
this . loginFormUrl = loginFormUrl ;
this . loginFormUrl = loginFormUrl ;
}
}
@ -77,59 +172,32 @@ public class AuthenticationProcessingFilterEntryPoint
public void commence ( ServletRequest request , ServletResponse response )
public void commence ( ServletRequest request , ServletResponse response )
throws IOException , ServletException {
throws IOException , ServletException {
HttpServletRequest req = ( HttpServletRequest ) request ;
HttpServletRequest req = ( HttpServletRequest ) request ;
String contextPath = req . getContextPath ( ) ;
String contextPath = req . getContextPath ( ) ;
String redirectUrl = contextPath + loginFormUrl ;
String redirectUrl = contextPath + loginFormUrl ;
if ( forceHttps & & req . getScheme ( ) . equals ( "http" ) ) {
if ( forceHttps & & req . getScheme ( ) . equals ( "http" ) ) {
Integer httpPort = new Integer ( req . getServerPort ( ) ) ;
Integer httpPort = new Integer ( req . getServerPort ( ) ) ;
Integer httpsPort = ( Integer ) httpsPortMapping . get ( httpPort ) ;
Integer httpsPort = ( Integer ) httpsPortMappings . get ( httpPort ) ;
if ( httpsPort ! = null ) {
if ( httpsPort ! = null ) {
String serverName = req . getServerName ( ) ;
String serverName = req . getServerName ( ) ;
redirectUrl = "https://" + serverName + ":" + httpsPort + contextPath
redirectUrl = "https://" + serverName + ":" + httpsPort
+ loginFormUrl ;
+ contextPath + loginFormUrl ;
}
}
}
}
( ( HttpServletResponse ) response ) . sendRedirect ( redirectUrl ) ;
( ( HttpServletResponse ) response ) . sendRedirect ( redirectUrl ) ;
}
}
public void setForceHttps ( boolean forceSsl ) {
this . forceHttps = forceSsl ;
}
public boolean getForceHttps ( ) {
return forceHttps ;
}
/ * *
* @throws IllegalArgumentException if input map does not consist of String keys
* and values , each representing an integer port number for one mapping .
* /
public void setHttpsPortMapping ( HashMap newMappings ) {
httpsPortMapping . clear ( ) ;
Iterator it = newMappings . entrySet ( ) . iterator ( ) ;
while ( it . hasNext ( ) ) {
Map . Entry entry = ( Map . Entry ) it . next ( ) ;
Integer httpPort = new Integer ( ( String ) entry . getKey ( ) ) ;
Integer httpsPort = new Integer ( ( String ) entry . getValue ( ) ) ;
if ( httpPort . intValue ( ) < 1 | | httpPort . intValue ( ) > 65535 | |
httpsPort . intValue ( ) < 1 | | httpsPort . intValue ( ) > 65535 )
throw new IllegalArgumentException ( "one or both ports out of legal range: "
+ httpPort + ", " + httpsPort ) ;
httpsPortMapping . put ( httpPort , httpsPort ) ;
if ( httpsPortMapping . size ( ) < 1 )
throw new IllegalArgumentException ( "must map at least one port" ) ;
}
}
/ * *
/ * *
* Returns the translated ( Integer - > Integer ) version of the original port
* Returns the translated ( Integer - > Integer ) version of the original port
* mapping specified via setHttpsPortMapping ( )
* mapping specified via setHttpsPortMapping ( )
*
* @return DOCUMENT ME !
* /
* /
protected HashMap getTranslatedHttpsPortMapping ( ) {
protected HashMap getTranslatedHttpsPortMappings ( ) {
return httpsPortMapping ;
return httpsPortMappings ;
}
}
}
}