Spring Security(3.1)を使用するWebアプリがあり、3つの異なるロール(ROLE_ADMIN、ROLE_CONS、ROLE_S_CEN)があります。
ROLE_ADMINの役割を持つユーザーでログインすると、すべてが期待どおりに機能しますが、ROLE_CONSの役割を持つ別のユーザーでログインすると、機能しません...
これが私のsecurity-context.xmlです
<?xml version="1.0" encoding="ISO-8859-1"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- preauthentication -->
<security:global-method-security pre-post-annotations="enabled">
</security:global-method-security>
<security:http auto-config="false" use-expressions="true" entry-point-ref="http403EntryPoint" access-denied-page="/autenticacion/accesodenegado">
<security:intercept-url pattern="/" access="permitAll"/>
<security:intercept-url pattern="/403.jsp" access="permitAll"/>
<!-- Allow non-secure access to static resources -->
<security:intercept-url pattern="/resources/**" access="permitAll"/>
<security:intercept-url pattern="/autenticacion/**" access="permitAll"/>
<!-- URLs que dependen de perfiles -->
<security:intercept-url pattern="/gestion/facturas/**" access="hasAnyRole('ROLE_ADMIN','ROLE_S_CEN','ROLE_CONS')"/>
<security:intercept-url pattern="/gestion/tarifas/**" access="hasAnyRole('ROLE_ADMIN','ROLE_S_CEN','ROLE_CONS')"/>
<security:intercept-url pattern="/gestion/envios/**" access="hasAnyRole('ROLE_ADMIN','ROLE_S_CEN')"/>
<security:intercept-url pattern="/gestion/perfiles/**" access="hasRole('ROLE_ADMIN')"/>
<security:intercept-url pattern="/gestion/usuarios/**" access="hasRole('ROLE_ADMIN')"/>
<security:intercept-url pattern="/consulta/**" access="hasAnyRole('ROLE_CONS','ROLE_ADMIN','ROLE_S_CEN')"/>
<security:intercept-url pattern="/importacion/**" access="hasAnyRole('ROLE_ADMIN','ROLE_S_CEN')"/>
<!-- Pantalla a la que redirige el logout -->
<security:logout logout-success-url="/"/>
</security:http>
<bean id="http403EntryPoint" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint">
</bean>
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<security:filter-chain-map path-type="ant">
<security:filter-chain pattern="/**" filters="j2eePreAuthFilter"/>
</security:filter-chain-map>
</bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref='preAuthenticatedAuthenticationProvider'/>
</security:authentication-manager>
<bean id="preAuthenticatedAuthenticationProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService" ref="preAuthenticatedUserDetailsService"/>
</bean>
<bean id="preAuthenticatedUserDetailsService"
class="org.springframework.security.web.authentication.preauth.PreAuthenticatedGrantedAuthoritiesUserDetailsService"/>
<bean id="j2eePreAuthFilter" class="es.myapp.security.MyAppUserJ2eePreAuthenticatedProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationDetailsSource" ref="authenticationDetailsSource"/>
<property name="continueFilterChainOnUnsuccessfulAuthentication" value="false"/>
</bean>
<bean id="authenticationDetailsSource" class="org.springframework.security.web.authentication.preauth.j2ee.J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource">
<property name="mappableRolesRetriever" ref="j2eeMappableRolesRetriever"/>
<property name="userRoles2GrantedAuthoritiesMapper" ref="j2eeUserRoles2GrantedAuthoritiesMapper"/>
</bean>
<bean id="j2eeMappableRolesRetriever" class="org.springframework.security.web.authentication.preauth.j2ee.WebXmlMappableAttributesRetriever">
</bean>
<bean id="j2eeUserRoles2GrantedAuthoritiesMapper" class="org.springframework.security.core.authority.mapping.SimpleAttributes2GrantedAuthoritiesMapper">
<property name="attributePrefix" value="test"/>
</bean>
</beans>
そして私のmenu.jsp
<%@ taglib uri="http://www.springframework.org/tags" prefix="s"%>
<%@ taglib uri="/WEB-INF/security.tld" prefix="sec"%>
<div class="inner">
<sec:authorize access="isAuthenticated()">
<ul id="menu">
<li>
<a href="#"><span id="padre" class="abierto"><s:message code="menu.conexion.capri"/></span></a>
<div class="sub_menu">
<ul>
<sec:authorize access="hasAnyRole('ROLE_ADMIN','ROLE_S_CEN')">
<li>
<a href="<s:url value="/importacion/datos"/>"><span><s:message code="menu.importacion.importarDatos"/></span></a>
</li>
</sec:authorize>
<sec:authorize access="hasAnyRole('ROLE_ADMIN','ROLE_S_CEN')">
<li>
<a href="<s:url value="/gestion/envios"/>"><span><s:message code="menu.gestion.envios"/></span></a>
</li>
</sec:authorize>
<sec:authorize access="hasAnyRole('ROLE_ADMIN','ROLE_S_CEN','ROLE_CONS')">
<li>
<a href="<s:url value="/consulta/envios"/>"><span><s:message code="menu.consulta.envios"/></span></a>
</li>
</sec:authorize>
<sec:authorize access="hasAnyRole('ROLE_ADMIN','ROLE_S_CEN')">
<li>
<a href="<s:url value="/gestion/facturas"/>"><span><s:message code="menu.gestion.facturas"/></span></a>
</li>
</sec:authorize>
<sec:authorize access="hasAnyRole('ROLE_ADMIN','ROLE_S_CEN','ROLE_CONS')">
<li>
<a href="<s:url value="/gestion/tarifas"/>"><span><s:message code="menu.gestion.tarifas"/></span></a>
</li>
</sec:authorize>
<li>
<a href="<s:url value="/gestion/envios/verpaginarecibir"/>"><span><s:message code="menu.recibir.envios"/></span></a>
</li>
</ul>
</div>
</li>
<sec:authorize access="hasRole('ROLE_ADMIN')">
<li>
<a href="#"><span id="padre" class="abierto"><s:message code="menu.usuarios"/></span></a>
<div class="sub_menu">
<ul>
<sec:authorize access="hasRole('ROLE_ADMIN')">
<li>
<a href="<s:url value="/gestion/usuarios"/>"><span><s:message code="menu.gestion.usuarios"/></span></a>
</li>
</sec:authorize>
<sec:authorize access="hasRole('ROLE_ADMIN')">
<li>
<a href="<s:url value="/gestion/perfiles"/>"><span><s:message code="menu.gestion.perfiles"/></span></a>
</li>
</sec:authorize>
</ul>
</div>
</li>
</sec:authorize>
</ul>
</sec:authorize>
</div>
ROLE_CONSの役割を持つユーザーでログインすると、セキュリティのないページとURLのみが表示されますが、ROLE_CONSがROLE_CONSに表示を許可されているものは表示されません...
ユーザーが適切に認証されており、権限としてROLE_CONSを持っていることをすでに確認しました...
何か案は?
ROLE_CONSでログインしたときにmenu.jspによって生成されたHTMLを追加するように編集しました。
<ul id="menu">
<li>
<a href="#"><span id="padre" class="abierto">Conexión CAPRI</span></a>
<div class="sub_menu">
<ul>
<li>
<a href="/myApp/gestion/envios/verpaginarecibir"><span>Recibir envíos</span></a>
</li>
</ul>
</div>
</li>
</ul>
そして、これは私がログインしたときのDEBUG出力です:
INFO : Spring Security Debugger -
************************************************************
Request received for '/autenticacion/inicio?lang=es':
org.apache.catalina.connector.RequestFacade@5b34329b
servletPath:/autenticacion/inicio
pathInfo:null
Security filter chain: [
SecurityContextPersistenceFilter
LogoutFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
]
************************************************************
DEBUG: es.myApp.security.MyAppUserJ2eePreAuthenticatedProcessingFilter - Checking secure context token: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@bf1d7451: Principal: org.springframework.security.core.userdetails.User@27a6eeec: Username: centro1; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_CONS ; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_CONS
DEBUG: es.myApp.controller.MyAppDispatcherServlet - DispatcherServlet with name 'Spring MVC Dispatcher Servlet' processing GET request for [/myApp/autenticacion/inicio]
DEBUG: es.myApp.controller.MyAppDispatcherServlet - Last-Modified value for [/myApp/autenticacion/inicio] is: -1
DEBUG: es.myApp.controller.MyAppDispatcherServlet - Rendering view [org.springframework.web.servlet.view.JstlView: name 'inicio'; URL [/WEB-INF/jsp/inicio.jsp]] in DispatcherServlet with name 'Spring MVC Dispatcher Servlet'
DEBUG: es.myApp.controller.MyAppDispatcherServlet - Successfully completed request
これはMyAppUserJ2eePreAuthenticatedProcessingFilterです
package es.myApp.security;
import java.util.ArrayList;
import java.util.Collection;
import javax.servlet.http.HttpServletRequest;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
import es.myApp.Constantes;
import es.myApp.modelo.datos.dominio.usuario.Perfil;
import es.myApp.security.impl.MyAppGrantedAuthorityImpl;
public class MyAppUserJ2eePreAuthenticatedProcessingFilter extends AbstractPreAuthenticatedProcessingFilter {
@Override
protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
MyAppUser usuario = (MyAppUser)request.getSession().getAttribute(Constantes.USUARIO_SESION);
return usuario.getCredentials();
}
@Override
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
MyAppUser user = (MyAppUser)request.getSession().getAttribute(Constantes.USUARIO_SESION);
if (user.getLogin() != null) {
Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for (Perfil p: user.getPerfiles()) {
authorities.add(new MyAppGrantedAuthorityImpl(p.getCodPerfil()));
}
}
return user;
}
}
そしてここにMyAppGrantedAuthorityImplがあります
package es.myappsecurity.impl;
import es.myappsecurity.MyAppGrantedAuthority;
@SuppressWarnings("serial")
public class MyAppGrantedAuthorityImpl implements MyAppGrantedAuthority {
private String autority;
public MyAppGrantedAuthorityImpl(String autority) {
super();
this.autority = autority;
}
public void setAutority(String autority) {
this.autority = autority;
}
@Override
public String getAuthority() {
return this.autority;
}
@Override
public String toString() {
return this.autority;
}
}