java - example - ¿Dos reinos en la misma aplicación con Spring Security?
spring-security-taglibs (3)
No puedo pensar en una forma directa de tener dos reinos (y no lo intenté yo mismo):
puede definir dos filtros en su web.xml donde cada uno de ellos tenga una configuración de resorte diferente y crear un entorno propio. Las cosas globales entran en la configuración de la aplicación, la específica del reino en la configuración del filtro.
si es solo para un método de autenticación diferente, puede escribir su propio filtro que luego decide a qué filtro llamar.
Estamos creando una aplicación web que está disponible para usuarios autenticados y anónimos. Si decide no registrarse / iniciar sesión, solo tiene un conjunto limitado de funciones. La autenticación del usuario se realiza sobre OpenID con Spring Security. Eso funciona bien.
Sin embargo, la aplicación también viene con una IU de administrador que se implementa en <host>/<context-root>/admin
. ¿Podemos tener dos reinos separados con Spring Security (por ejemplo, autenticación básica para /admin/**
)? ¿Cómo se debe configurar eso?
Solución posible:
- Agregue un interceptor de URL para
/admin
requiere "ROLE_ADMIN" - Configure la instancia de
org.springframework.security.web.authentication.www.BasicAuthenticationFilter
para interceptar la URL/admin
y autenticar al usuario como ROLE_ADMIN si proporciona las credenciales apropiadas
Configuración de muestra:
<security:intercept-url pattern="/admin" access="ROLE_ADMIN"/>
<bean id="basicAuthenticationEntryPoint"
class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint">
<property name="realmName"
value="WS realm"/>
</bean>
<bean id="basicAuthenticationProcessingFilter"
class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter">
<property name="authenticationManager"
ref="authenticationManager"/>
<property name="authenticationEntryPoint"
ref="basicAuthenticationEntryPoint"/>
</bean>
Nota: la implementación predeterminada de BasicAuthenticationFilter es un filtro pasivo, es decir, solo busca un encabezado de autenticación básico en la solicitud y, si no está presente, no hace nada. Si desea que el filtro requiera explícitamente la autenticación básica del cliente, necesita extender la implementación predeterminada para comenzar al punto de entrada de autenticación:
public class BasicAuthenticationFilter
extends org.springframework.security.web.authentication.www.BasicAuthenticationFilter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) req;
final HttpServletResponse response = (HttpServletResponse) res;
String header = request.getHeader("Authorization");
if ((header != null) && header.startsWith("Basic ")) {
super.doFilter(req, res, chain);
} else {
getAuthenticationEntryPoint().commence(request, response, new AuthenticationCredentialsNotFoundException("Missing credentials"));
}
}
}
Además, debe ajustar el filtro para que se aplique solo a la URL de /admin
, ya sea codificándolo por doFilter
en el método doFilter
o proporcionando un bean contenedor apropiado.
Spring Security ha agregado soporte para este escenario en la versión 3.1, que actualmente está disponible como un candidato de lanzamiento. Fue implementado por SEC-1171 y los detalles de la sintaxis se encuentran en el manual incluido en 3.1.
Sin embargo es bastante simple de usar. Básicamente, simplemente define varios elementos http
en su configuración de Spring Security, uno para cada dominio. Lo estamos utilizando así:
<!-- Configure realm for system administration users -->
<security:http pattern="/admin/**" create-session="stateless">
<security:intercept-url pattern=''/**'' access=''ROLE_ADMIN'' requires-channel="https" />
<security:http-basic/>
</security:http>
<!-- Configure realm for standard users -->
<security:http auto-config="true" access-denied-page="/error/noaccess" use-expressions="true" create-session="ifRequired">
<security:form-login login-page="/login"
...
...
</security:http>
La clave a tener en cuenta es el pattern="/admin/**"
en el primer elemento http
. Esto le indica a Spring que todas las URL bajo /admin
están sujetas a ese dominio en lugar del reino predeterminado, y por lo tanto las URL bajo /admin
usan autenticación básica en su lugar.