0

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;
    }

}
4

2 に答える 2

1

これは機能するはずなので、この状況の潜在的な問題の原因を見つけようとします。

  1. sec taglibにカスタムURIを使用します:<%@ taglib uri="/WEB-INF/security.tld" prefix="sec"%>-なぜ標準URIではないのですか?Mavenを使用していますか?

  2. MyAppUserJ2eePreAuthenticatedProcessingFilterコードを表示できますか?

  3. <security:http>名前空間config の両方を使用します<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">が、これは潜在的な問題になる可能性があります。これを中に追加してみてください<http>

    <sec:custom-filter ref="j2eePreAuthFilter" position="PRE_AUTH_FILTER" />
    

    ちなみに、Spring Security 3.1では、複数の要素を作成できます<http>

編集:

問題がどこにあるかはわかっていると思います... equalses.myApp.modelo.datos.dominio.security.impl.MyAppGrantedAuthorityImplhashCodeは適切に実装されていますか?ソースコードを見せてもらえますか?

extend SimpleGrantedAuthority implements MyAppGrantedAuthorityこの実装を実行または試すことができます。

public class MyAppGrantedAuthorityImpl implements MyAppGrantedAuthority {

    private String autority;

    public MyAppGrantedAuthorityImpl(String autority) {
        super();
        if (autority == null || autority.isEmpty()) {
            throw new IllegalArgumentException("Authority cannot be empty");
        }
        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;
    }

    public boolean equals(Object obj) {
        if (obj instanceof String) {
            return obj.equals(this.autority);
        }

        if (obj instanceof GrantedAuthority) {
            GrantedAuthority attr = (GrantedAuthority) obj;

            return this.autority.equals(attr.getAuthority());
        }

        return false;
    }

    public int hashCode() {
        return this.autority.hashCode();
    }

}
于 2012-09-11T10:28:22.853 に答える
0

さて、これは本当に奇妙です...ロール名をROLE_CONSからROLE_CONSLに変更すると、機能します...データベースのフィールドが10文字の長さであるためだと思います...他の説明は見つかりませんでした... O_o

機能したすべての役割は10文字の長さです(ROLE_ADMINおよびROLE_S_CEN)。失敗した役割は9文字でした。

とにかく、jspで役割名を印刷したとき、それは「ROLE_CONS」などではなく9文字だったので、非常に奇妙です...

于 2012-09-11T11:37:50.513 に答える