j_spring_security_check - Inicio de sesión HTTPS con Spring Security redirige a HTTP
spring security tutorial (6)
Tengo una aplicación web Spring, asegurada con Spring Security, que se ejecuta en EC2. Delante de la instancia EC2 hay un Elastic Load Balancer con un certificado SSL (https termina en el balanceador de carga, es decir, el puerto 443 -> puerto 80), por lo que desde la perspectiva de Tomcat, las solicitudes entrantes son HTTP.
Mi formulario de inicio de sesión se envía a https, sin embargo, el redireccionamiento posterior va a http (éxito o fracaso). La autenticación fue exitosa, y puedo volver a https y estoy conectado.
Mi configuración de inicio de sesión se ve así:
<security:form-login
default-target-url="/home"
login-page="/"
login-processing-url="/processlogin"
authentication-failure-url="/?login_error=1"/>
¿Qué debo cambiar para que la URL de destino predeterminada y la URL de error de autenticación vayan a https?
- Tomcat 6
- Spring Security 3.0.x
Configuro require-channel = "any" en todas las URL de intercepción. Esto permite que siga funcionando en mi entorno de desarrollo donde no utilizo SSL.
<intercept-url pattern="/createUser" access="permitAll" requires-channel="any"/>
<intercept-url pattern="/admin/**" access="hasRole(''ROLE_ADMIN'')" requires-channel="any"/>
<intercept-url pattern="/**" access="isAuthenticated()" requires-channel="any"/>
Luego, cree un host virtual apache que redirija todo el tráfico a la versión HTTPS.
<VirtualHost *:80>
ServerName www.mywebsite.com
Redirect permanent / https://www.mywebsite.com/
</VirtualHost>
Si se trata de una aplicación Spring Boot (uso actualmente la versión 2.0.0), la siguiente configuración dentro del archivo application.properties
debería ser suficiente:
server.tomcat.protocol-header=x-forwarded-proto
Esto funcionó para mí en AWS con un equilibrador de carga en la parte delantera.
Para Spring Boot <2.0.0 también debería funcionar (no probado)
Su configuración de resorte debe ser independiente del protocolo utilizado. Si utiliza algo como "requiere canal", tarde o temprano tendrá problemas, especialmente si desea implementar la misma aplicación en un entorno de desarrollo sin https.
En su lugar, considere configurar su tomcat correctamente. Puedes hacer esto con RemoteIpValve . Dependiendo de qué encabezados envíe el equilibrador de carga, su configuración server.xml debe contener algo como esto:
<Valve
className="org.apache.catalina.valves.RemoteIpValve"
internalProxies=".*"
protocolHeader="X-Forwarded-Proto"
httpsServerPort="443"
/>
Spring determinará la dirección de redirección absoluta basada en ServletRequest, así que cambie el httpsServerPort si está utilizando algo más que 443:
El httpsServerPort es el puerto devuelto por ServletRequest.getServerPort () cuando el protocolHeader indica el protocolo https
También estoy enfrentando exactamente el mismo problema y hasta el momento en que obtengo la solución adecuada, estoy redirigiendo mis solicitudes del servidor proxy al servidor tomcat sobre AJP en lugar de HTTP. A continuación está mi configuración de apache
ProxyPass /myproject ajp://localhost:8009/myproject
ProxyPassReverse /myproject ajp://localhost:8009/myproject
Una manera de hacerlo funcionar es agregando las siguientes configuraciones
<http auto-config="true" use-expressions="true" entry-point-ref="authenticationEntryPoint" >
<form-login login-page="/login.jsf" authentication-failure-url="/login.jsf?login_error=t" always-use-default-target="true" default-target-url="xxxxx" />
<logout logout-url="/logout" logout-success-url="/logoutSuccess.jsf" />
...
</http>
Tuvo que agregar always-use-default-target="true"
y default-target-url="https://...."
. No es la forma ideal, ya que necesita codificar la url en la configuración.
utilice las siguientes líneas de código en web.xml
<security-constraint>
<web-resource-collection>
<web-resource-name>Login and Restricted Space URLs</web-resource-name>
<url-pattern>/j_security_check</url-pattern>
<url-pattern>/loginpage.rose</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
obliga a usar HTTPS.